Merge remote-tracking branch 'remotes/origin/pr/1080'
# Conflicts: # BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj merges PR #1080 closes PR #1080 (let's see if either of these can do it)
This commit is contained in:
commit
b179a30d99
|
@ -0,0 +1,149 @@
|
|||
function round(num, numDecimalPlaces)
|
||||
local mult = 10^(numDecimalPlaces or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
function get_baseline()
|
||||
i = 100
|
||||
client.reboot_core()
|
||||
t = os.clock()
|
||||
|
||||
while i > 0 do
|
||||
emu.frameadvance()
|
||||
i = i - 1
|
||||
end
|
||||
baseline = os.clock() - t
|
||||
print('Baseline: ' .. round(baseline, 3) .. " secs")
|
||||
return baseline
|
||||
end
|
||||
|
||||
function test_mmf()
|
||||
i = 100
|
||||
client.reboot_core()
|
||||
t = os.clock()
|
||||
while i > 0 do
|
||||
emu.frameadvance()
|
||||
comm.mmfScreenshot()
|
||||
i = i - 1
|
||||
end
|
||||
print('Memory mapped files: ' .. round((os.clock() - t - baseline), 3) .. " secs")
|
||||
end
|
||||
|
||||
function test_http()
|
||||
print("Testing HTTP server")
|
||||
client.reboot_core()
|
||||
i = 100
|
||||
t = os.clock()
|
||||
|
||||
while i > 0 do
|
||||
emu.frameadvance()
|
||||
comm.httpTestGet()
|
||||
i = i - 1
|
||||
end
|
||||
print('HTTP get: ' .. round((os.clock() - t - baseline), 3) .. " secs")
|
||||
|
||||
client.reboot_core()
|
||||
i = 100
|
||||
t = os.clock()
|
||||
|
||||
while i > 0 do
|
||||
emu.frameadvance()
|
||||
comm.httpPostScreenshot()
|
||||
i = i - 1
|
||||
end
|
||||
print('HTTP post: ' .. round((os.clock() - t - baseline), 3) .. " secs")
|
||||
|
||||
end
|
||||
|
||||
function test_socket()
|
||||
|
||||
i = 100
|
||||
client.reboot_core()
|
||||
t = os.clock()
|
||||
while i > 0 do
|
||||
emu.frameadvance()
|
||||
comm.socketServerScreenShot()
|
||||
i = i - 1
|
||||
end
|
||||
print('Socket server: ' .. round((os.clock() - t - baseline), 3) .. " secs")
|
||||
end
|
||||
|
||||
function test_socketresponse()
|
||||
best_time = -100
|
||||
timeouts = {1, 2, 3, 4, 5, 10, 20, 25, 50, 100, 250, 500, 1000}
|
||||
comm.socketServerSetTimeout(1000)
|
||||
resp = comm.socketServerScreenShotResponse()
|
||||
for t, timeout in ipairs(timeouts) do
|
||||
comm.socketServerSetTimeout(timeout)
|
||||
client.reboot_core()
|
||||
print("Trying to find minimal timeout for Socket server")
|
||||
i = 100
|
||||
t = os.clock()
|
||||
while i > 0 do
|
||||
emu.frameadvance()
|
||||
resp = comm.socketServerScreenShotResponse()
|
||||
if resp ~= 'ack' then
|
||||
i = -100
|
||||
print(resp)
|
||||
print("Failed to a get a proper response")
|
||||
end
|
||||
i = i - 1
|
||||
end
|
||||
if i > -100 then
|
||||
print("Best timeout: " .. timeout .. " msecs")
|
||||
print("Best time: " .. round((os.clock() - t - baseline), 3) .. " secs")
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function test_http_response()
|
||||
err = false
|
||||
print("Testing HTTP server response")
|
||||
client.reboot_core()
|
||||
i = 100
|
||||
|
||||
while i > 0 do
|
||||
emu.frameadvance()
|
||||
resp = comm.httpTestGet()
|
||||
if resp ~= "<html><body><h1>hi!</h1></body></html>" then
|
||||
print("Failed to get correct HTTP get response")
|
||||
print(resp)
|
||||
i = 0
|
||||
err = true
|
||||
end
|
||||
i = i - 1
|
||||
end
|
||||
if not err then
|
||||
print("HTTP GET looks fine: No errors occurred")
|
||||
end
|
||||
|
||||
client.reboot_core()
|
||||
i = 100
|
||||
err = false
|
||||
while i > 0 do
|
||||
emu.frameadvance()
|
||||
resp = comm.httpPostScreenshot()
|
||||
if resp ~= "<html><body>OK</body></html>" then
|
||||
print("Failed to get correct HTTP post response")
|
||||
print(resp)
|
||||
i = 0
|
||||
err = true
|
||||
end
|
||||
i = i - 1
|
||||
end
|
||||
if not err then
|
||||
print("HTTP POST looks fine: No errors occurred")
|
||||
end
|
||||
end
|
||||
|
||||
baseline = get_baseline()
|
||||
test_socket()
|
||||
test_mmf()
|
||||
test_http()
|
||||
print("#####################")
|
||||
test_http_response()
|
||||
test_socketresponse()
|
||||
print()
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
print("##########################################################")
|
||||
getUrl = comm.httpGetGetUrl()
|
||||
print("GET URL: " .. getUrl)
|
||||
|
||||
postUrl = comm.httpGetPostUrl()
|
||||
print("POST URL: " .. postUrl)
|
||||
|
||||
print("\nChecking GET URL change")
|
||||
error = false
|
||||
comm.httpSetGetUrl('a')
|
||||
if (getUrl ~= comm.httpGetGetUrl()) then
|
||||
comm.httpSetGetUrl(getUrl)
|
||||
error = (getUrl ~= comm.httpGetGetUrl())
|
||||
else
|
||||
error = true
|
||||
end
|
||||
|
||||
if error == false then
|
||||
print("Get URL was successfully changed")
|
||||
else
|
||||
print("Error while changing Get URL")
|
||||
end
|
||||
|
||||
|
||||
print("\nChecking POST URL change")
|
||||
error = false
|
||||
comm.httpSetPostUrl('a')
|
||||
if (postUrl ~= comm.httpGetPostUrl()) then
|
||||
comm.httpSetPostUrl(postUrl)
|
||||
error = (postUrl ~= comm.httpGetPostUrl())
|
||||
else
|
||||
error = true
|
||||
end
|
||||
|
||||
if error == false then
|
||||
print("Post URL was successfully changed")
|
||||
else
|
||||
print("Error while changing Post URL")
|
||||
end
|
||||
|
||||
print("\nChecking GET request")
|
||||
getResponse = comm.httpGet("http://tasvideos.org/BizHawk.html")
|
||||
if string.find(getResponse, "Bizhawk") then
|
||||
print("GET seems to work")
|
||||
else
|
||||
print("Either the Bizhawk site is down or the GET does not work")
|
||||
end
|
||||
|
||||
print("\nChecking memory mapped filed")
|
||||
|
||||
size = comm.mmfScreenshot()
|
||||
if size > 0 then
|
||||
print("Memory mapped file was successfully written")
|
||||
else
|
||||
print("Failed to write memory mapped file")
|
||||
end
|
||||
|
||||
mmf_filename = comm.mmfGetFilename()
|
||||
print("MMF filename: " .. mmf_filename)
|
||||
comm.mmfSetFilename("deleteme.tmp")
|
||||
error = false
|
||||
if (mmf_filename ~= comm.mmfGetFilename()) then
|
||||
comm.mmfSetFilename(mmf_filename)
|
||||
error = (mmf_filename ~= comm.mmfGetFilename())
|
||||
else
|
||||
error = true
|
||||
end
|
||||
if error == false then
|
||||
print("MMF filename successfully changed")
|
||||
else
|
||||
print("MMF filename change failed")
|
||||
end
|
||||
|
||||
print("Writing to MMF")
|
||||
|
||||
message = "ABC"
|
||||
resp_n = tonumber(comm.mmfWrite(mmf_filename, message))
|
||||
if (resp_n ~= string.len(message)) then
|
||||
print("Failed to write to MMF")
|
||||
else
|
||||
resp = comm.mmfRead(mmf_filename, string.len(message))
|
||||
if (resp ~= message) then
|
||||
print("Failed to read from MMF")
|
||||
else
|
||||
print("MMF read and read OK")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
print("\nTests finished")
|
||||
print("Please run TestCommunication_All.lua with the supplied Python server for a more comprehensive test")
|
|
@ -27,11 +27,14 @@ namespace BizHawk.Client.EmuHawk
|
|||
public bool luaConsole = false;
|
||||
public int socket_port = 9999;
|
||||
public string socket_ip = null;
|
||||
public string mmf_filename = null;
|
||||
public string URL_get = null;
|
||||
public string URL_post = null;
|
||||
|
||||
public void ParseArguments(string[] args)
|
||||
|
||||
public void parseArguments(string[] args)
|
||||
|
||||
{
|
||||
for (int i = 0; i<args.Length; i++)
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
// For some reason sometimes visual studio will pass this to us on the commandline. it makes no sense.
|
||||
if (args[i] == ">")
|
||||
|
@ -62,8 +65,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
else if (arg.StartsWith("--dump-frames="))
|
||||
{
|
||||
var list = arg.Substring(arg.IndexOf('=') + 1);
|
||||
var items = list.Split(',');
|
||||
string list = arg.Substring(arg.IndexOf('=') + 1);
|
||||
string[] items = list.Split(',');
|
||||
_currAviWriterFrameList = new HashSet<int>();
|
||||
foreach (string item in items)
|
||||
{
|
||||
|
@ -110,11 +113,55 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
socket_ip = arg.Substring(arg.IndexOf('=') + 1);
|
||||
}
|
||||
else if (arg.StartsWith("--mmf="))
|
||||
{
|
||||
mmf_filename = args[i].Substring(args[i].IndexOf('=') + 1);
|
||||
}
|
||||
else if (arg.StartsWith("--url_get="))
|
||||
{
|
||||
URL_get = args[i].Substring(args[i].IndexOf('=') + 1);
|
||||
}
|
||||
else if (arg.StartsWith("--url_post="))
|
||||
{
|
||||
URL_post = args[i].Substring(args[i].IndexOf('=') + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdRom = args[i];
|
||||
}
|
||||
}
|
||||
////initialize HTTP communication
|
||||
if (URL_get != null || URL_post != null)
|
||||
{
|
||||
if (URL_get != null)
|
||||
{
|
||||
GlobalWin.httpCommunication.initialized = true;
|
||||
GlobalWin.httpCommunication.SetGetUrl(URL_get);
|
||||
}
|
||||
if (URL_post != null)
|
||||
{
|
||||
GlobalWin.httpCommunication.initialized = true;
|
||||
GlobalWin.httpCommunication.SetPostUrl(URL_post);
|
||||
}
|
||||
}
|
||||
//inititalize socket server
|
||||
if (socket_ip != null && socket_port > -1)
|
||||
{
|
||||
GlobalWin.socketServer.initialized = true;
|
||||
GlobalWin.socketServer.SetIp(socket_ip, socket_port);
|
||||
}
|
||||
else if (socket_ip != null)
|
||||
{
|
||||
GlobalWin.socketServer.initialized = true;
|
||||
GlobalWin.socketServer.SetIp(socket_ip);
|
||||
}
|
||||
|
||||
//initialize mapped memory files
|
||||
if (mmf_filename != null)
|
||||
{
|
||||
GlobalWin.memoryMappedFiles.initialized = true;
|
||||
GlobalWin.memoryMappedFiles.SetFilename(mmf_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Xaml" />
|
||||
<Reference Include="System.Xml.Linq">
|
||||
|
@ -197,6 +198,7 @@
|
|||
<Compile Include="BizBoxInfoControl.Designer.cs">
|
||||
<DependentUpon>BizBoxInfoControl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Communication.cs" />
|
||||
<Compile Include="config\AnalogRangeConfig.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
@ -877,6 +879,7 @@
|
|||
<DependentUpon>NewHexEditor.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Client.cs" />
|
||||
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Communication.cs" />
|
||||
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Console.cs" />
|
||||
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.cs" />
|
||||
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Forms.cs" />
|
||||
|
@ -2179,4 +2182,4 @@
|
|||
<PreBuildEvent />
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)Build\Common.targets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -0,0 +1,445 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Http;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using BizHawk.Bizware.BizwareGL;
|
||||
using System.Drawing;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
||||
public class Communication
|
||||
{
|
||||
|
||||
public class HttpCommunication
|
||||
{
|
||||
private static HttpClient client = new HttpClient();
|
||||
private string PostUrl = "http://localhost:9876/post/";
|
||||
private string GetUrl = "http://localhost:9876/index";
|
||||
public bool initialized = false;
|
||||
private ScreenShot screenShot = new ScreenShot();
|
||||
public int timeout = 0;
|
||||
public int default_timeout = 500;
|
||||
|
||||
public void SetTimeout(int _timeout)
|
||||
{
|
||||
//timeout = _timeout.TotalMilliseconds;
|
||||
if (timeout == 0 && _timeout == 0)
|
||||
{
|
||||
timeout = default_timeout;
|
||||
}
|
||||
if (_timeout != 0)
|
||||
{
|
||||
client.Timeout = new TimeSpan(0, 0, 0, _timeout / 1000, _timeout % 1000);
|
||||
timeout = _timeout;
|
||||
}
|
||||
|
||||
}
|
||||
public void SetPostUrl(string url)
|
||||
{
|
||||
PostUrl = url;
|
||||
}
|
||||
public void SetGetUrl(string url)
|
||||
{
|
||||
GetUrl = url;
|
||||
}
|
||||
|
||||
public string GetGetUrl()
|
||||
{
|
||||
return GetUrl;
|
||||
}
|
||||
public string GetPostUrl()
|
||||
{
|
||||
return PostUrl;
|
||||
}
|
||||
|
||||
public async Task<string> Get(string url)
|
||||
{
|
||||
client.DefaultRequestHeaders.ConnectionClose = false;
|
||||
HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
|
||||
if (response.IsSuccessStatusCode) {
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> Post(string url, FormUrlEncodedContent content)
|
||||
{
|
||||
client.DefaultRequestHeaders.ConnectionClose = true;
|
||||
HttpResponseMessage response = null;
|
||||
try
|
||||
{
|
||||
response = await client.PostAsync(url, content).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.ToString());
|
||||
return e.ToString();
|
||||
|
||||
}
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
public string TestGet()
|
||||
{
|
||||
Task<String> getResponse = Get(GetUrl);
|
||||
return getResponse.Result;
|
||||
}
|
||||
|
||||
public string SendScreenshot(string url, string parameter)
|
||||
{
|
||||
int trials = 5;
|
||||
var values = new Dictionary<string, string>
|
||||
{
|
||||
{parameter, screenShot.GetScreenShotAsString()},
|
||||
};
|
||||
FormUrlEncodedContent content = new FormUrlEncodedContent(values);
|
||||
|
||||
Task<string> postResponse = null;
|
||||
while (postResponse == null && trials > 0)
|
||||
{
|
||||
postResponse = Post(PostUrl, content);
|
||||
trials -= 1;
|
||||
}
|
||||
return postResponse.Result;
|
||||
}
|
||||
|
||||
public string SendScreenshot()
|
||||
{
|
||||
return SendScreenshot(PostUrl, "screenshot");
|
||||
}
|
||||
|
||||
public string SendScreenshot(string url)
|
||||
{
|
||||
return SendScreenshot(url, "screenshot");
|
||||
}
|
||||
|
||||
public string ExecGet(string url)
|
||||
{
|
||||
return Get(url).Result;
|
||||
}
|
||||
|
||||
public string ExecGet()
|
||||
{
|
||||
return Get(GetUrl).Result;
|
||||
}
|
||||
|
||||
public string ExecPost(string url, string payload)
|
||||
{
|
||||
var values = new Dictionary<string, string>
|
||||
{
|
||||
{"payload", payload},
|
||||
};
|
||||
FormUrlEncodedContent content = new FormUrlEncodedContent(values);
|
||||
return Post(url, content).Result;
|
||||
}
|
||||
|
||||
public string ExecPost(string payload)
|
||||
{
|
||||
var values = new Dictionary<string, string>
|
||||
{
|
||||
{"payload", payload},
|
||||
};
|
||||
FormUrlEncodedContent content = new FormUrlEncodedContent(values);
|
||||
return Post(PostUrl, content).Result;
|
||||
}
|
||||
}
|
||||
public class SocketServer
|
||||
{
|
||||
|
||||
public string ip = "192.168.178.21";
|
||||
public int port = 9999;
|
||||
public Decoder decoder = Encoding.UTF8.GetDecoder();
|
||||
public Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
public IPAddress ipAdd;
|
||||
public IPEndPoint remoteEP;
|
||||
public IVideoProvider currentVideoProvider = null;
|
||||
public bool connected = false;
|
||||
public bool initialized = false;
|
||||
public int retries = 10;
|
||||
public bool success = false; //indicates whether the last command was executed succesfully
|
||||
|
||||
public void Initialize(IVideoProvider _currentVideoProvider)
|
||||
{
|
||||
currentVideoProvider = _currentVideoProvider;
|
||||
SetIp(ip, port);
|
||||
initialized = true;
|
||||
|
||||
}
|
||||
public void Connect()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
Initialize(currentVideoProvider);
|
||||
}
|
||||
remoteEP = new IPEndPoint(ipAdd, port);
|
||||
soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
soc.Connect(remoteEP);
|
||||
connected = true;
|
||||
soc.ReceiveTimeout = 5;
|
||||
|
||||
}
|
||||
public void SetIp(string ip_)
|
||||
{
|
||||
ip = ip_;
|
||||
ipAdd = System.Net.IPAddress.Parse(ip);
|
||||
remoteEP = new IPEndPoint(ipAdd, port);
|
||||
}
|
||||
public void SetIp(string ip_, int port_)
|
||||
{
|
||||
ip = ip_;
|
||||
port = port_;
|
||||
ipAdd = System.Net.IPAddress.Parse(ip);
|
||||
remoteEP = new IPEndPoint(ipAdd, port);
|
||||
|
||||
}
|
||||
public void SetTimeout(int timeout)
|
||||
{
|
||||
soc.ReceiveTimeout = timeout;
|
||||
}
|
||||
public void SocketConnected()
|
||||
{
|
||||
bool part1 = soc.Poll(1000, SelectMode.SelectRead);
|
||||
bool part2 = (soc.Available == 0);
|
||||
if (part1 && part2)
|
||||
connected = false;
|
||||
else
|
||||
connected = true;
|
||||
}
|
||||
public int SendString(string SendString)
|
||||
{
|
||||
|
||||
int sentBytes = SendBytes(Encoding.ASCII.GetBytes(SendString));
|
||||
success = sentBytes > 0;
|
||||
return sentBytes;
|
||||
}
|
||||
public int SendBytes(byte[] SendBytes)
|
||||
{
|
||||
int sentBytes = 0;
|
||||
try
|
||||
{
|
||||
sentBytes = soc.Send(SendBytes);
|
||||
}
|
||||
catch
|
||||
{
|
||||
sentBytes = -1;
|
||||
}
|
||||
return sentBytes;
|
||||
}
|
||||
|
||||
public string SendScreenshot()
|
||||
{
|
||||
return SendScreenshot(0);
|
||||
}
|
||||
public string SendScreenshot(int waitingTime)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
ScreenShot screenShot = new ScreenShot();
|
||||
using (BitmapBuffer bb = screenShot.MakeScreenShotImage())
|
||||
{
|
||||
using (var img = bb.ToSysdrawingBitmap())
|
||||
{
|
||||
byte[] bmpBytes = screenShot.ImageToByte(img);
|
||||
int sentBytes = 0;
|
||||
int tries = 0;
|
||||
while (sentBytes <= 0 && tries < retries)
|
||||
{
|
||||
try
|
||||
{
|
||||
tries++;
|
||||
sentBytes = SendBytes(bmpBytes);
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
Connect();
|
||||
sentBytes = 0;
|
||||
}
|
||||
if (sentBytes == -1)
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
}
|
||||
success = (tries < retries);
|
||||
}
|
||||
}
|
||||
String resp = "";
|
||||
if (!success)
|
||||
{
|
||||
resp = "Screenshot could not be sent";
|
||||
} else
|
||||
{
|
||||
resp = "Screenshot was sent";
|
||||
}
|
||||
if (waitingTime == 0)
|
||||
{
|
||||
return resp;
|
||||
}
|
||||
resp = "";
|
||||
resp = ReceiveMessage();
|
||||
if (resp == "")
|
||||
{
|
||||
resp = "Failed to get a response";
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
public string ReceiveMessage()
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
string resp = "";
|
||||
byte[] receivedBytes = new byte[256];
|
||||
int receivedLength = 1;
|
||||
|
||||
while (receivedLength > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
receivedLength = soc.Receive(receivedBytes, receivedBytes.Length, 0);
|
||||
resp += Encoding.ASCII.GetString(receivedBytes);
|
||||
} catch
|
||||
{
|
||||
receivedLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
public bool Successful()
|
||||
{
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
public class MemoryMappedFiles
|
||||
{
|
||||
public string filename_main = "BizhawkTemp_main";
|
||||
public Dictionary<string, MemoryMappedFile> mmf_files = new Dictionary<string, MemoryMappedFile>();
|
||||
public int index = 0;
|
||||
public bool initialized = false;
|
||||
public int main_size = 10 ^ 5;
|
||||
ScreenShot screenShot = new ScreenShot();
|
||||
|
||||
public void SetFilename(string filename)
|
||||
{
|
||||
filename_main = filename;
|
||||
}
|
||||
public string GetFilename()
|
||||
{
|
||||
return filename_main;
|
||||
}
|
||||
|
||||
public int ScreenShotToFile()
|
||||
{
|
||||
ScreenShot screenShot = new ScreenShot();
|
||||
var bb = screenShot.MakeScreenShotImage();
|
||||
var img = bb.ToSysdrawingBitmap();
|
||||
byte[] bmpBytes = screenShot.ImageToByte(img);
|
||||
return WriteToFile(@filename_main, bmpBytes);
|
||||
}
|
||||
|
||||
public int WriteToFile(string filename, byte[] outputBytes)
|
||||
{
|
||||
MemoryMappedFile mmf_file;
|
||||
int bytesWritten = -1;
|
||||
if (mmf_files.TryGetValue(filename, out mmf_file) == false)
|
||||
{
|
||||
mmf_file = MemoryMappedFile.CreateOrOpen(filename, outputBytes.Length);
|
||||
mmf_files[filename] = mmf_file;
|
||||
}
|
||||
try
|
||||
{
|
||||
using (MemoryMappedViewAccessor accessor = mmf_file.CreateViewAccessor(0, outputBytes.Length, MemoryMappedFileAccess.Write))
|
||||
{
|
||||
accessor.WriteArray<byte>(0, outputBytes, 0, outputBytes.Length);
|
||||
bytesWritten = outputBytes.Length;
|
||||
}
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
try
|
||||
{
|
||||
mmf_file.Dispose();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
mmf_file = MemoryMappedFile.CreateOrOpen(filename, outputBytes.Length);
|
||||
mmf_files[filename] = mmf_file;
|
||||
using (MemoryMappedViewAccessor accessor = mmf_file.CreateViewAccessor(0, outputBytes.Length, MemoryMappedFileAccess.Write))
|
||||
{
|
||||
accessor.WriteArray<byte>(0, outputBytes, 0, outputBytes.Length);
|
||||
bytesWritten = outputBytes.Length;
|
||||
}
|
||||
}
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
public string ReadFromFile(string filename, int expectedSize)
|
||||
{
|
||||
MemoryMappedFile mmf_file = mmf_file = MemoryMappedFile.OpenExisting(@filename);
|
||||
using (MemoryMappedViewAccessor viewAccessor = mmf_file.CreateViewAccessor())
|
||||
{
|
||||
byte[] bytes = new byte[expectedSize];
|
||||
viewAccessor.ReadArray(0, bytes, 0, bytes.Length);
|
||||
string text = Encoding.UTF8.GetString(bytes);
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ScreenShot
|
||||
//makes all functionalities for providing screenshots available
|
||||
{
|
||||
private IVideoProvider currentVideoProvider = null;
|
||||
private ImageConverter converter = new ImageConverter();
|
||||
public BitmapBuffer MakeScreenShotImage()
|
||||
{
|
||||
if (currentVideoProvider == null)
|
||||
{
|
||||
currentVideoProvider = Global.Emulator.AsVideoProviderOrDefault();
|
||||
}
|
||||
return GlobalWin.DisplayManager.RenderVideoProvider(currentVideoProvider);
|
||||
}
|
||||
public byte[] ImageToByte(Image img)
|
||||
{
|
||||
return (byte[])converter.ConvertTo(img, typeof(byte[]));
|
||||
}
|
||||
public string ImageToString(Image img)
|
||||
{
|
||||
return Convert.ToBase64String(ImageToByte(img));
|
||||
}
|
||||
public string GetScreenShotAsString()
|
||||
{
|
||||
BitmapBuffer bb = MakeScreenShotImage();
|
||||
byte[] imgBytes = ImageToByte(bb.ToSysdrawingBitmap());
|
||||
return Convert.ToBase64String(imgBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,5 +24,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
public static GLManager GLManager;
|
||||
|
||||
public static int ExitCode;
|
||||
public static Communication.HttpCommunication httpCommunication = new Communication.HttpCommunication();
|
||||
public static Communication.SocketServer socketServer = new Communication.SocketServer();
|
||||
public static Communication.MemoryMappedFiles memoryMappedFiles = new Communication.MemoryMappedFiles();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
};
|
||||
|
||||
argParse.parseArguments(args);
|
||||
argParse.ParseArguments(args);
|
||||
|
||||
Database.LoadDatabase(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb.txt"));
|
||||
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using NLua;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Client.Common;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
[Description("A library for communicating with other programs")]
|
||||
public sealed class CommunicationLuaLibrary : LuaLibraryBase
|
||||
{
|
||||
[RequiredService]
|
||||
private IEmulator Emulator { get; set; }
|
||||
|
||||
[RequiredService]
|
||||
private IVideoProvider VideoProvider { get; set; }
|
||||
|
||||
public CommunicationLuaLibrary(Lua lua)
|
||||
: base(lua) { }
|
||||
|
||||
public CommunicationLuaLibrary(Lua lua, Action<string> logOutputCallback)
|
||||
: base(lua, logOutputCallback) { }
|
||||
|
||||
public override string Name => "comm";
|
||||
|
||||
//TO DO: not fully working yet!
|
||||
[LuaMethod("getluafunctionslist", "returns a list of implemented functions")]
|
||||
public static string GetLuaFunctionsList()
|
||||
{
|
||||
var list = new StringBuilder();
|
||||
foreach (var function in typeof(CommunicationLuaLibrary).GetMethods())
|
||||
{
|
||||
list.AppendLine(function.ToString());
|
||||
}
|
||||
|
||||
return list.ToString();
|
||||
}
|
||||
|
||||
[LuaMethod("socketServerScreenShot", "sends a screenshot to the Socket server")]
|
||||
public string SocketServerScreenShot()
|
||||
{
|
||||
return GlobalWin.socketServer.SendScreenshot();
|
||||
}
|
||||
[LuaMethod("socketServerScreenShotResponse", "sends a screenshot to the Socket server and retrieves the response")]
|
||||
public string SocketServerScreenShotResponse()
|
||||
{
|
||||
return GlobalWin.socketServer.SendScreenshot(1000).ToString();
|
||||
}
|
||||
|
||||
[LuaMethod("socketServerSend", "sends a string to the Socket server")]
|
||||
public string SocketServerSend(string SendString)
|
||||
{
|
||||
return "Sent : " + GlobalWin.socketServer.SendString(SendString).ToString() + " bytes";
|
||||
}
|
||||
[LuaMethod("socketServerResponse", "receives a message from the Socket server")]
|
||||
public string SocketServerResponse()
|
||||
{
|
||||
return GlobalWin.socketServer.ReceiveMessage();
|
||||
}
|
||||
|
||||
[LuaMethod("socketServerSuccessful", "returns the status of the last Socket server action")]
|
||||
public bool SocketServerSuccessful()
|
||||
{
|
||||
return GlobalWin.socketServer.Successful();
|
||||
}
|
||||
[LuaMethod("socketServerSetTimeout", "sets the timeout in milliseconds for receiving messages")]
|
||||
public void SocketServerSetTimeout(int timeout)
|
||||
{
|
||||
GlobalWin.socketServer.SetTimeout(timeout);
|
||||
}
|
||||
// All MemoryMappedFile related methods
|
||||
[LuaMethod("mmfSetFilename", "Sets the filename for the screenshots")]
|
||||
public void MmfSetFilename(string filename)
|
||||
{
|
||||
GlobalWin.memoryMappedFiles.SetFilename(filename);
|
||||
}
|
||||
[LuaMethod("mmfGetFilename", "Gets the filename for the screenshots")]
|
||||
public string MmfSetFilename()
|
||||
{
|
||||
return GlobalWin.memoryMappedFiles.GetFilename();
|
||||
}
|
||||
|
||||
[LuaMethod("mmfScreenshot", "Saves screenshot to memory mapped file")]
|
||||
public int MmfScreenshot()
|
||||
{
|
||||
return GlobalWin.memoryMappedFiles.ScreenShotToFile();
|
||||
}
|
||||
|
||||
[LuaMethod("mmfWrite", "Writes a string to a memory mapped file")]
|
||||
public int MmfWrite(string mmf_filename, string outputString)
|
||||
{
|
||||
return GlobalWin.memoryMappedFiles.WriteToFile(mmf_filename, Encoding.ASCII.GetBytes(outputString));
|
||||
}
|
||||
[LuaMethod("mmfRead", "Reads a string from a memory mapped file")]
|
||||
public string MmfRead(string mmf_filename, int expectedSize)
|
||||
{
|
||||
return GlobalWin.memoryMappedFiles.ReadFromFile(mmf_filename, expectedSize).ToString();
|
||||
}
|
||||
// All HTTP related methods
|
||||
[LuaMethod("httpTest", "tests HTTP connections")]
|
||||
public string HttpTest()
|
||||
{
|
||||
var list = new StringBuilder();
|
||||
list.AppendLine(GlobalWin.httpCommunication.TestGet());
|
||||
list.AppendLine(GlobalWin.httpCommunication.SendScreenshot());
|
||||
list.AppendLine("done testing");
|
||||
return list.ToString();
|
||||
}
|
||||
[LuaMethod("httpTestGet", "tests the HTTP GET connection")]
|
||||
public string HttpTestGet()
|
||||
{
|
||||
return GlobalWin.httpCommunication.TestGet();
|
||||
}
|
||||
[LuaMethod("httpGet", "makes a HTTP GET request")]
|
||||
public string HttpGet(string url)
|
||||
{
|
||||
return GlobalWin.httpCommunication.ExecGet(url);
|
||||
}
|
||||
|
||||
[LuaMethod("httpPost", "makes a HTTP POST request")]
|
||||
public string HttpPost(string url, string payload)
|
||||
{
|
||||
return GlobalWin.httpCommunication.ExecPost(url, payload);
|
||||
}
|
||||
[LuaMethod("httpPostScreenshot", "HTTP POST screenshot")]
|
||||
public string HttpPostScreenshot()
|
||||
{
|
||||
return GlobalWin.httpCommunication.SendScreenshot();
|
||||
}
|
||||
[LuaMethod("httpSetTimeout", "Sets HTTP timeout in milliseconds")]
|
||||
public void HttpSetTimeout(int timeout)
|
||||
{
|
||||
GlobalWin.httpCommunication.SetTimeout(timeout);
|
||||
}
|
||||
[LuaMethod("httpSetPostUrl", "Sets HTTP POST URL")]
|
||||
public void HttpSetPostUrl(string url)
|
||||
{
|
||||
GlobalWin.httpCommunication.SetPostUrl(url);
|
||||
}
|
||||
[LuaMethod("httpSetGetUrl", "Sets HTTP GET URL")]
|
||||
public void HttpSetGetUrl(string url)
|
||||
{
|
||||
GlobalWin.httpCommunication.SetGetUrl(url);
|
||||
}
|
||||
[LuaMethod("httpGetPostUrl", "Gets HTTP POST URL")]
|
||||
public string HttpGetPostUrl()
|
||||
{
|
||||
return GlobalWin.httpCommunication.GetPostUrl();
|
||||
}
|
||||
[LuaMethod("httpGetGetUrl", "Gets HTTP GET URL")]
|
||||
public string HttpGetGetUrl()
|
||||
{
|
||||
return GlobalWin.httpCommunication.GetGetUrl();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue