diff --git a/Assets/Lua/UnitTests/TestCommunication_All.lua b/Assets/Lua/UnitTests/TestCommunication_All.lua new file mode 100644 index 00000000000..4e1a7e95b39 --- /dev/null +++ b/Assets/Lua/UnitTests/TestCommunication_All.lua @@ -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 ~= "

hi!

" 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 ~= "OK" 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() + diff --git a/Assets/Lua/UnitTests/TestCommunication_Simple.lua b/Assets/Lua/UnitTests/TestCommunication_Simple.lua new file mode 100644 index 00000000000..b7b5fac6472 --- /dev/null +++ b/Assets/Lua/UnitTests/TestCommunication_Simple.lua @@ -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") diff --git a/BizHawk.Client.EmuHawk/ArgParser.cs b/BizHawk.Client.EmuHawk/ArgParser.cs index eae8c11fdfd..0912c68ba93 100644 --- a/BizHawk.Client.EmuHawk/ArgParser.cs +++ b/BizHawk.Client.EmuHawk/ArgParser.cs @@ -27,11 +27,14 @@ class ArgParser 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") @@ -62,8 +65,8 @@ public void parseArguments(string[] args) } 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(); foreach (string item in items) { @@ -110,11 +113,55 @@ public void parseArguments(string[] args) { 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); + } } } } diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 46d339fb4a0..0fa83153e47 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -96,6 +96,7 @@ 3.5 + @@ -197,6 +198,7 @@ BizBoxInfoControl.cs + Component @@ -877,6 +879,7 @@ NewHexEditor.cs + @@ -2179,4 +2182,4 @@ - + \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/Communication.cs b/BizHawk.Client.EmuHawk/Communication.cs new file mode 100644 index 00000000000..ba61cd16716 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Communication.cs @@ -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 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 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 getResponse = Get(GetUrl); + return getResponse.Result; + } + + public string SendScreenshot(string url, string parameter) + { + int trials = 5; + var values = new Dictionary + { + {parameter, screenShot.GetScreenShotAsString()}, + }; + FormUrlEncodedContent content = new FormUrlEncodedContent(values); + + Task 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 + { + {"payload", payload}, + }; + FormUrlEncodedContent content = new FormUrlEncodedContent(values); + return Post(url, content).Result; + } + + public string ExecPost(string payload) + { + var values = new Dictionary + { + {"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 mmf_files = new Dictionary(); + 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(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(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); + } + } + } +} + diff --git a/BizHawk.Client.EmuHawk/GlobalWin.cs b/BizHawk.Client.EmuHawk/GlobalWin.cs index e0137c6e4a8..5df3f651bfe 100644 --- a/BizHawk.Client.EmuHawk/GlobalWin.cs +++ b/BizHawk.Client.EmuHawk/GlobalWin.cs @@ -24,5 +24,8 @@ public static class GlobalWin 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(); } } diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index a696112c457..d653e066919 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -155,7 +155,7 @@ public MainForm(string[] args) } }; - argParse.parseArguments(args); + argParse.ParseArguments(args); Database.LoadDatabase(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb.txt")); diff --git a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Communication.cs b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Communication.cs new file mode 100644 index 00000000000..fdae9f132d8 --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Communication.cs @@ -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 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(); + } + } +}