static void InputServer(InputClient client)
{
Console.Error.WriteLine("Start input server");
HashSet<byte> keysDown = new HashSet<byte>();
CloseHandler.SetCloseHandler(() =>
{
System.IO.File.WriteAllText("serverCloseLog.txt", "Server closing, resetting keys:\r\n");
foreach (byte keycode in keysDown)
{
client.KeyUp(keycode);
System.IO.File.AppendAllText("serverCloseLog.txt", "KeyCode: " + keycode + "\r\n");
}
client.MouseUp(MouseButton.Left);
client.MouseUp(MouseButton.Right);
client.MouseUp(MouseButton.Middle);
});
// we work on a line by line basis
string line;
while ((line = Console.ReadLine()) != null)
{
client.ResetScreenSaver();
// we can process multiple commands in a single line separated by ;
foreach (string linePart in line.Split(new char[]{';'}, StringSplitOptions.RemoveEmptyEntries))
{
// Add to history
s_events.Add(linePart);
while (s_events.Count > MAX_EVENTS_HISTORY) s_events.RemoveAt(0);
// split by space
string[] parts = linePart.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
switch (parts[0])
{
case "mm":
// Mouse move
// x = parts[1], y = parts[2]
double x = double.Parse(parts[1]);
double y = double.Parse(parts[2]);
int width, height;
client.GetScreenSize(out width, out height);
int xPixel = (int)(x * width);
int yPixel = (int)(y * height);
if (xPixel > width) xPixel = width;
if (yPixel > height) yPixel = height;
client.MouseMove(xPixel, yPixel);
break;
case "mmr":
// Relative mouse move
// x change = parts[1], y change = parts[2]
int xDiff = int.Parse(parts[1]);
int yDiff = int.Parse(parts[2]);
client.MouseMoveRelative(xDiff, yDiff);
break;
case "m":
case "md":
case "mu":
// Mouse click
// clickType == parts[1], l = left, m = middle, r = right
MouseButton btn = MouseButton.Left;
if (parts[1] == "m") {
btn = MouseButton.Middle;
}
else if (parts[1] == "r")
{
btn = MouseButton.Right;
}
if (parts[0] == "m")
{
client.MouseClick(btn);
}
else if (parts[0] == "md")
{
client.MouseDown(btn);
}
else if (parts[0] == "mu")
{
client.MouseUp(btn);
}
else
{
throw new Exception("Forgot to update some strings somewhere?");
}
break;
case "k":
case "kd":
case "ku":
// Keyboard button
byte keycode = byte.Parse(parts[1]);
if (parts[0] == "k")
{
client.KeyDown(keycode);
client.KeyUp(keycode);
}
else if (parts[0] == "kd")
{
keysDown.Add(keycode);
client.KeyDown(keycode);
}
else if (parts[0] == "ku")
{
if (keysDown.Contains(keycode)) keysDown.Remove(keycode);
client.KeyUp(keycode);
}
else
{
throw new Exception("Forgot to update some strings somewhere?");
}
break;
case "sy":
case "sx":
int scrollDelta = (int)(double.Parse(parts[1]) * 120);
client.MouseScroll(scrollDelta, parts[0] == "sx");
break;
case "s":
// Get screen size
int screenW, screenH;
client.GetScreenSize(out screenW, out screenH);
Console.WriteLine("{0} {1}", screenW, screenH);
break;
case "ss":
// Take screenshot - dir to save is first param, returns file saved (including dir name)
// image width/height are 2nd and 3rd params, anything <= 0 means ignore it and use native res
int sWidth = int.Parse(parts[2]);
int sHeight = int.Parse(parts[3]);
ThreadPool.QueueUserWorkItem(o =>
{
Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
string filename = APPPATH + System.IO.Path.DirectorySeparatorChar + client.Screenshot(parts[1], sWidth, sHeight);
Console.WriteLine("==screenshot==");
Console.WriteLine(filename);
Console.WriteLine("<><>");
});
break;
case "clear":
// Reset all the current keys that are down
foreach (byte keyCode in keysDown)
{
client.KeyUp(keyCode);
}
keysDown.Clear();
break;
case "debug":
// start of output
Console.WriteLine("==debug==");
Console.WriteLine("Event History:");
foreach (string e in s_events)
{
Console.WriteLine(" " + e);
}
Console.WriteLine("Key Downs:");
foreach (byte k in keysDown)
{
Console.WriteLine(" " + k);
}
// end of output
Console.WriteLine("<><>");
break;
default:
throw new InvalidOperationException("Protocol Violation");
}
}
}
Console.Error.WriteLine("Input server closed");
}