
I'm trying to merge UDPpacketVBuffer and SafeUDPpacketV. Seems pretty messy so far... hopefully this is fruitful.
313 lines
5.4 KiB
C++
313 lines
5.4 KiB
C++
#include "debug.h"
|
|
#include "lib_SDL_common.h" /* SDL* */
|
|
#include "signal_common.h"
|
|
#include "unused.h"
|
|
#include "events_common.h"
|
|
#include "trim.h"
|
|
#include "lib_lua_common.h"
|
|
#include "util.h"
|
|
#include "Server.h"
|
|
#include "Commands.h"
|
|
#include "lib_GetOpt.h"
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
#include <stdlib.h> /* exit */
|
|
#include <unistd.h> /* getopt */
|
|
#include <getopt.h> /* getopt */
|
|
|
|
static bool done = false;
|
|
static const char* prompt_str = "> ";
|
|
|
|
/* XXX gross */
|
|
static std::vector<char> server_data;
|
|
static bool left_shift = false;
|
|
|
|
static std::unique_ptr<Server> server;
|
|
|
|
static bool my_SDL_UserEvent (SDL_Event *);
|
|
static int my_StdinThread(void*);
|
|
static void my_ProcessPacket (UDPpacket *);
|
|
static bool my_StdinThread_Helper (const std::string&);
|
|
static void my_ShowPrompt (void);
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
Init_CommonOpts init_opts;
|
|
SDL_Event ev;
|
|
|
|
common_GetOpt (argc, argv, &init_opts);
|
|
common_Signal_Init ();
|
|
common_SDL_Init ();
|
|
|
|
server = std::make_unique<Server> (init_opts.host, init_opts.port);
|
|
|
|
if (server->Start () < 0)
|
|
{
|
|
SDL_Log ("Couldn't start server!");
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
done = false;
|
|
SDL_Thread* stdin_loop = SDL_CreateThread(my_StdinThread, "my_StdinThread", (void*)NULL);
|
|
if (NULL == stdin_loop)
|
|
{
|
|
error ("SDL_CreateThread failed: %s\n", SDL_GetError());
|
|
}
|
|
|
|
while (!done)
|
|
{
|
|
SDL_Delay (1);
|
|
while (!done && SDL_PollEvent (&ev))
|
|
{
|
|
switch (ev.type)
|
|
{
|
|
case SDL_QUIT:
|
|
done = true;
|
|
break;
|
|
case PACKET_SDL_EVENT:
|
|
{
|
|
done = my_SDL_UserEvent (&ev);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
server->Stop ();
|
|
// server->CloseAllSockets ();
|
|
|
|
SDL_WaitThread (stdin_loop, NULL);
|
|
|
|
common_SDL_Quit ();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static bool
|
|
my_SDL_UserEvent (SDL_Event * ev)
|
|
{
|
|
SDL_assert (NULL != ev);
|
|
switch (ev->user.type)
|
|
{
|
|
case PACKET_SDL_EVENT:
|
|
{
|
|
UDPpacket* packet = (UDPpacket *) ev->user.data1;
|
|
if (packet)
|
|
{
|
|
// SDL_Log ("PACKET_SDL_EVENT");
|
|
my_ProcessPacket (packet);
|
|
SDLNet_FreePacket (packet);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/* XXX gross */
|
|
static void
|
|
my_ProcessPacket (UDPpacket* packet)
|
|
{
|
|
char c;
|
|
size_t len;
|
|
SDL_Event event;
|
|
|
|
if (!packet)
|
|
return;
|
|
SDL_assert (NULL != packet);
|
|
if (!packet->len)
|
|
return;
|
|
SDL_assert (packet->len > 0);
|
|
|
|
len = packet->len;
|
|
if (len > sizeof (SDL_Event))
|
|
len = sizeof (SDL_Event);
|
|
SDL_memcpy (&event, packet->data, len);
|
|
|
|
// SDL_Log ("%d, %x", packet->len, event.type);
|
|
|
|
if (!((event.type == SDL_KEYDOWN) || (event.type == SDL_KEYUP)))
|
|
{
|
|
util_UDP_DumpPacket (packet);
|
|
return;
|
|
}
|
|
|
|
std::string str = std::string (SDL_GetKeyName (event.key.keysym.sym));
|
|
bool down = (event.type == SDL_KEYDOWN);
|
|
|
|
// SDL_Log ("%d \"%s\"", str.length (), str.c_str ());
|
|
|
|
/* XXX ultra gross */
|
|
if (down)
|
|
{
|
|
if (str.length () > 1)
|
|
{
|
|
if (str == "Return")
|
|
{
|
|
server_data.push_back ('\0');
|
|
std::string buf = std::string ((const char*)server_data.data ());
|
|
printf ("\n => ");
|
|
fflush (stdout);
|
|
server->RunLua (buf);
|
|
fflush (stdout);
|
|
server_data.clear ();
|
|
}
|
|
else if (str == "Left Shift")
|
|
{
|
|
left_shift = (bool) true;
|
|
}
|
|
else if (str == "Space")
|
|
{
|
|
server_data.push_back (' ');
|
|
putchar (' ');
|
|
fflush (stdout);
|
|
}
|
|
else if (str == "Backspace")
|
|
{
|
|
off_t size = server_data.size () - 1;
|
|
if (size < 0)
|
|
size = 0;
|
|
server_data.resize (size);
|
|
printf ("\x08\e[0K");
|
|
fflush (stdout);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
c = tolower (str[0]);
|
|
if (isalpha (c))
|
|
{
|
|
if (left_shift)
|
|
c = toupper (c);
|
|
}
|
|
else if (isdigit (c))
|
|
{
|
|
const char* sym = ")!@#$%^&*(";
|
|
if (left_shift)
|
|
c = sym[c - '0'];
|
|
}
|
|
else
|
|
{
|
|
if (left_shift)
|
|
{
|
|
switch (c)
|
|
{
|
|
case '\'': c = '"'; break;
|
|
case ',': c = '<'; break;
|
|
case '-': c = '_'; break;
|
|
case '.': c = '>'; break;
|
|
case '/': c = '?'; break;
|
|
case ';': c = ':'; break;
|
|
case '=': c = '+'; break;
|
|
case '[': c = '{'; break;
|
|
case '\\': c = '|'; break;
|
|
case ']': c = '}'; break;
|
|
case '`': c = '~'; break;
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
server_data.push_back (c);
|
|
putchar (c);
|
|
fflush (stdout);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (str == "Left Shift")
|
|
{
|
|
left_shift = (bool) false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void my_ShowPrompt (void)
|
|
{
|
|
printf ("\n%s", prompt_str);
|
|
fflush (stdout);
|
|
}
|
|
|
|
|
|
/*
|
|
* TODO
|
|
* Oh boy this would be our main command handler for the server stdin huh? Wowie!
|
|
*/
|
|
static bool my_StdinThread_Helper (const std::string& buf)
|
|
{
|
|
std::string argv0 = buf;
|
|
std::string args = buf;
|
|
|
|
auto const& pos = buf.find (' ');
|
|
if (pos != std::string::npos)
|
|
{
|
|
/* command <args> */
|
|
argv0 = buf.substr (0, pos);
|
|
argv0 = trim (argv0);
|
|
args = buf.substr (pos);
|
|
}
|
|
|
|
// SDL_Log ("\"%s\"", argv0.c_str ());
|
|
|
|
auto const& ref = CommandFunctionList.find (argv0);
|
|
if (ref != CommandFunctionList.end ())
|
|
{
|
|
/* It was found */
|
|
return ref->second (args);
|
|
}
|
|
|
|
SDL_Delay (100);
|
|
return false;
|
|
}
|
|
|
|
|
|
static int my_StdinThread(void* param)
|
|
{
|
|
std::string buf;
|
|
UNUSED (param);
|
|
|
|
_top:
|
|
while (!done)
|
|
{
|
|
my_ShowPrompt ();
|
|
try
|
|
{
|
|
getline (std::cin, buf);
|
|
}
|
|
catch (std::ifstream::failure& e)
|
|
{
|
|
done = true;
|
|
}
|
|
if (std::cin.bad () || std::cin.eof ())
|
|
{
|
|
done = true;
|
|
goto _out;
|
|
}
|
|
buf = trim (buf);
|
|
if (buf.empty ())
|
|
{
|
|
goto _top;
|
|
}
|
|
if ((done = my_StdinThread_Helper (buf)))
|
|
{
|
|
goto _out;
|
|
}
|
|
}
|
|
_out:
|
|
|
|
return 0;
|
|
}
|