--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto2/Application.cc Sat Nov 08 18:02:58 2008 +0000
@@ -0,0 +1,115 @@
+
+#include "Engine.hh"
+
+#include <stdexcept>
+#include <cassert>
+
+#include <ClanLib/core.h>
+#include <ClanLib/application.h>
+
+class ArgumentError : public std::exception {
+ private:
+ const char *message;
+
+ public:
+ ArgumentError (const std::string &message) : message(message.c_str()) { }
+
+ virtual const char* what() const throw() {
+ return message;
+ }
+};
+
+class Main : public CL_ClanApplication {
+ private:
+ // arguments
+ CL_CommandLine args;
+
+ std::string arg_port;
+ bool arg_dedicated;
+ std::string arg_connect;
+
+ void parse_args (int argc, char **argv) {
+ // set up the options
+ args.add_option('p', "port", "PORT", "set network port used", true);
+ args.add_option('D', "dedicated", "", "act as a network server", true);
+ args.add_option('c', "connect", "SERVERHOST", "act as a network client", true);
+
+ // set defaults
+ arg_port = NETWORK_PORT_STR;
+ arg_dedicated = false;
+ arg_connect = "";
+
+ try {
+ // parse args
+ args.parse_args(argc, argv);
+ } catch (CL_Error &e) {
+ throw ArgumentError(e.message);
+ }
+
+ while (args.next()) {
+ switch (args.get_key()) {
+ case 'p':
+ arg_port = args.get_argument();
+ break;
+
+ case 'D':
+ arg_dedicated = true;
+ break;
+
+ case 'c':
+ arg_connect = args.get_argument();
+ break;
+
+ case CL_CommandLine::REST_ARG:
+ throw ArgumentError(args.get_argument());
+
+ default:
+ throw ArgumentError(std::string(1, (char) args.get_key()));
+
+ }
+ }
+
+ // check for valid combinations of arugments
+ if (arg_dedicated && !arg_connect.empty())
+ throw ArgumentError("-D and -c are mutually exclusive");
+
+ if (!arg_dedicated && arg_connect.empty())
+ throw ArgumentError("nothing to do");
+ }
+
+ public:
+ virtual int main (int argc, char **argv) {
+ // initialize core
+ CL_SetupCore setup_core;
+
+ try {
+ // parse arugments
+ parse_args(argc, argv);
+
+ // run engine based on args
+ if (arg_dedicated) {
+ Engine::runNetworkServer(arg_port);
+
+ } else if (!arg_connect.empty()) {
+ Engine::runNetworkClient(arg_connect, arg_port);
+
+ } else
+ assert(false);
+
+ // succesful return
+ return 0;
+
+ } catch (ArgumentError &e) {
+ std::cerr << e.what() << std::endl;
+ args.print_help();
+
+ // XXX: handle --help
+
+ } catch (std::exception &e) {
+ std::cerr << e.what() << std::endl;
+
+ return 1;
+ }
+ }
+} app;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto2/Engine.cc Sat Nov 08 18:02:58 2008 +0000
@@ -0,0 +1,68 @@
+
+#include "Engine.hh"
+#include "GameState.hh"
+#include "NetworkServer.hh"
+#include "NetworkClient.hh"
+
+Engine::Engine (void) : is_running(true) {
+
+}
+
+void Engine::runNetworkServer (const std::string &listen_port) {
+ // the engine
+ Engine engine;
+
+ // setup network
+ CL_SetupNetwork setup_network;
+
+ try {
+ // create the server
+ engine.net_server = new NetworkServer(engine.game_state, listen_port);
+
+ // run the main loop
+ engine.main_loop();
+
+ } catch (CL_Error &e) {
+ std::cerr << "NetworkServer::main: CL_Error:" << e.message << std::endl;
+
+ throw;
+ }
+}
+
+void Engine::runNetworkClient (const std::string &connect_host, const std::string &connect_port) {
+ // the engine
+ Engine engine;
+
+ // setup network
+ CL_SetupNetwork setup_network;
+
+ // connect_to
+ CL_IPAddress connect_addr(connect_host, connect_port);
+
+ try {
+ // create the server
+ engine.net_client = new NetworkClient(engine.game_state, connect_addr);
+
+ // run the main loop
+ engine.main_loop();
+
+ } catch (CL_Error &e) {
+ std::cerr << "NetworkServer::main: CL_Error:" << e.message << std::endl;
+
+ throw;
+ }
+
+}
+
+void Engine::main_loop (void) {
+ while (is_running) {
+ // this does.... magical things
+ CL_System::keep_alive();
+
+ // if I can't find some better way to do this in ClanLib by next thursday, then it f*%!ing sucks
+ // ideally, we should be able to have a main loop that does timed waits on I/O, fufilling some set of timers
+ // but as far as I can tell, ClanLib doesn't have anything like that
+ CL_System::sleep(100);
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto2/Engine.hh Sat Nov 08 18:02:58 2008 +0000
@@ -0,0 +1,27 @@
+
+#include "NetworkServer.hh"
+#include "NetworkClient.hh"
+
+class Engine {
+ private:
+ // game state
+ GameState game_state;
+
+ // network server/client
+ NetworkServer *net_server;
+ NetworkClient *net_client;
+
+ // to exit the mainloop
+ bool is_running;
+
+ // default constructor
+ Engine (void);
+
+ public:
+ static void runNetworkServer (const std::string &listen_port);
+ static void runNetworkClient (const std::string &connect_host, const std::string &connect_port);
+
+ private:
+ void main_loop (void);
+
+};
--- a/src/proto2/Network.hh Fri Nov 07 21:40:32 2008 +0000
+++ b/src/proto2/Network.hh Sat Nov 08 18:02:58 2008 +0000
@@ -1,25 +1,21 @@
#ifndef NETWORK_HH
#define NETWORK_HH
+#include "NetworkConfig.hh"
+#include "GameState.hh"
+
#include <ClanLib/network.h>
-#include "NetworkConfig.hh"
-
-class NetworkBase {
+class NetworkCore {
protected:
- CL_Socket socket;
+ GameState &state;
- NetworkBase () :
- socket(CL_Socket::udp)
- {
- socket.set_nonblocking(true);
- }
+ CL_SlotContainer slots;
- NetworkBase (CL_Socket socket) :
- socket(socket)
- {
- socket.set_nonblocking(true);
- }
+ CL_NetSession netsession;
+
+ // constructor
+ NetworkCore (GameState &state) : state(state), netsession(NETWORK_APP_NAME) { }
};
#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto2/NetworkClient.cc Sat Nov 08 18:02:58 2008 +0000
@@ -0,0 +1,9 @@
+
+#include "NetworkClient.hh"
+
+
+NetworkClient::NetworkClient (GameState &state, const CL_IPAddress &connect_to) :
+ NetworkCore(state), server(netsession.connect(connect_to)) {
+
+ // connect slots
+}
--- a/src/proto2/NetworkClient.hh Fri Nov 07 21:40:32 2008 +0000
+++ b/src/proto2/NetworkClient.hh Sat Nov 08 18:02:58 2008 +0000
@@ -1,12 +1,15 @@
#ifndef NETWORKCLIENT_HH
#define NETWORKCLIENT_HH
-class NetworkClient {
+#include "Network.hh"
+#include "GameState.hh"
+
+class NetworkClient : public NetworkCore {
private:
- GameState *state;
-
+ CL_NetComputer server;
+
public:
- NetworkClient (GameState *state);
+ NetworkClient (GameState &state, const CL_IPAddress &connect_to);
};
#endif
--- a/src/proto2/NetworkConfig.hh Fri Nov 07 21:40:32 2008 +0000
+++ b/src/proto2/NetworkConfig.hh Sat Nov 08 18:02:58 2008 +0000
@@ -1,6 +1,8 @@
#ifndef NETWORK_CONFIG_HH
#define NETWORK_CONFIG_HH
+// socket-related includes
+// copied from clanlib code, so should be relatively OS-safe
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
@@ -14,6 +16,9 @@
typedef int socklen_t;
#endif
+#include <string>
+
+const std::string NETWORK_APP_NAME = "KisnaGlista";
const std::string NETWORK_PORT_STR = "9338";
const uint16_t NETWORK_PACKET_MAX = 1280;
--- a/src/proto2/NetworkServer.cc Fri Nov 07 21:40:32 2008 +0000
+++ b/src/proto2/NetworkServer.cc Sat Nov 08 18:02:58 2008 +0000
@@ -4,82 +4,26 @@
#include <iostream>
#include <cassert>
-NetworkServer::NetworkServer (GameState *state, const CL_IPAddress &listen_ip) : NetworkBase(), state(state) {
- socket.bind(listen_ip);
+NetworkServer::NetworkServer (GameState &state, const std::string &listen_port) :
+ NetworkCore(state) {
- // add socket to listener
- listener.add_trigger(socket.get_read_trigger());
-
- // bind slot for recv
- slot_on_recv = socket.sig_read_triggered().connect(this, &NetworkServer::_onRecv);
+ // connect slots
+ slots.connect(netsession.sig_computer_connected(), this, &NetworkServer::on_connect);
+ slots.connect(netsession.sig_computer_disconnected(), this, &NetworkServer::on_disconnect);
+
+ // and then we listen
+ netsession.start_listen(listen_port);
}
-NetworkServer *NetworkServer::newServer (void) {
- GameState *state = new GameState(/* XXX */);
- CL_IPAddress listen_ip(NETWORK_PORT_STR);
-
- return new NetworkServer(state, listen_ip);
-}
-
-void NetworkServer::run (void) {
- bool isRunning = true;
-
- while (isRunning) {
- /* XXX: all I need to do? */
- listener.wait();
- CL_System::keep_alive();
- listener.reset_all();
- }
+void NetworkServer::on_connect (CL_NetComputer &computer) {
+ std::cout << "NetworkServer.on_connect: " << computer.get_address().get_address() << std::endl;
}
-void NetworkServer::_onRecv (void) {
- NetworkPacket pkt;
-
- pkt.recvFromSocket(socket);
-
- std::cout << pkt.src.get_address() << ":" << pkt.src.get_port() << " <- ";
-
- enum packet_type type = pkt.read_pkt_type();
-
- switch (type) {
- case PKT_HELLO:
- {
- pkt_Hello hello(pkt);
-
- std::cout << "\tPKT_HELLO: " << hello.player_id << std::endl;
- } break;
-
- default:
- {
- std::cout << "\t???:" << type << std::endl;
-
- } break;
- }
+void NetworkServer::on_disconnect (CL_NetComputer &computer) {
+ std::cout << "NetworkServer.on_disconnect: " << computer.get_address().get_address() << std::endl;
}
NetworkServerClient::NetworkServerClient (NetworkServer &server) : server(server) {
}
-
-void runNetworkServer (void) {
- NetworkServer *server = NULL;
-
- try {
- server = NetworkServer::newServer();
- server->run();
- } catch (CL_Error &e) {
- std::cerr << "runNetworkServer: CL_Error: " << e.message << std::endl;
- }
-}
-int main (int argc, char **argv) {
- // setup ClanLib components
- CL_SetupCore setup_core;
- CL_SetupNetwork setup_network;
-
- // create the gamestate and run the server
- runNetworkServer();
-
- return 0;
-}
-
--- a/src/proto2/NetworkServer.hh Fri Nov 07 21:40:32 2008 +0000
+++ b/src/proto2/NetworkServer.hh Sat Nov 08 18:02:58 2008 +0000
@@ -11,25 +11,13 @@
// forward-declare
class NetworkServerClient;
-class NetworkServer : public NetworkBase {
- private:
- GameState *state;
-
- std::map<CL_IPAddress, NetworkServerClient> client_sockets;
-
- CL_EventListener listener;
-
- CL_Slot slot_on_recv;
-
- NetworkServer (GameState *state, const CL_IPAddress &listen_ip);
-
+class NetworkServer : public NetworkCore {
public:
- static NetworkServer *newServer (void);
-
- void run (void);
+ NetworkServer (GameState &state, const std::string &listen_port);
private:
- void _onRecv (void);
+ void on_connect (CL_NetComputer &computer);
+ void on_disconnect (CL_NetComputer &computer);
};
class NetworkServerClient {
@@ -40,6 +28,4 @@
NetworkServerClient (NetworkServer &server);
};
-void runNetworkServer (void);
-
#endif