# HG changeset patch # User Bradley Arsenault # Date 1177632209 14400 # Node ID 8e2a122cbd5411f7dac77c12088836c8cc00f96e # Parent ddbedd4025c4ace6cb838174164a1a49e181ec86 added NetConnection class diff -r ddbedd4025c4 -r 8e2a122cbd54 src/NetConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/NetConnection.cpp Thu Apr 26 20:03:29 2007 -0400 @@ -0,0 +1,19 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "NetConnection.h" diff -r ddbedd4025c4 -r 8e2a122cbd54 src/NetConnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/NetConnection.h Thu Apr 26 20:03:29 2007 -0400 @@ -0,0 +1,33 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "SDL_net.h" + + +///Net connection represents a low level wrapper arround SDL. +///It queues Message(s) it recieves from the connection. +class NetConnection +{ + + + + + + + +}; # HG changeset patch # User Bradley Arsenault # Date 1177634598 14400 # Node ID f1f468cdf724bce1d48dd6ef1db87c0c53f149b7 # Parent 8e2a122cbd5411f7dac77c12088836c8cc00f96e Frameworked NetConnection class diff -r 8e2a122cbd54 -r f1f468cdf724 src/NetConnection.cpp --- a/src/NetConnection.cpp Thu Apr 26 20:03:29 2007 -0400 +++ b/src/NetConnection.cpp Thu Apr 26 20:43:18 2007 -0400 @@ -17,3 +17,92 @@ */ #include "NetConnection.h" + +NetConnection::NetConnection(const std::string& address, Uint16 port) +{ + connected = false; + openConnection(address, port); +} + + + +NetConnection::NetConnection() +{ + +} + + + +void NetConnection::openConnection(const std::string& address, Uint16 port) +{ + if(!connected) + { + //Resolve the address + if(SDLNet_ResolveHost(&address, ipaddress.c_str(), port) == -1) + { + printf("NetConnection::openConnection: %s\n", SDLNet_GetError()); + assert(false); + } + + //Open the connection + socket=SDLNet_TCP_Open(&address); + if(!socket) + { + printf("NetConnection::openConnection: %s\n", SDLNet_GetError()); + assert(false); + } + else + { + connected=true; + } + } +} + + + +void NetConnection::closeConnection() +{ + if(connected) + SDLNet_TCP_Close(socket); + connected=false; +} + + + +bool NetConnection::isConnected() +{ + return connected; +} + + + +Message NetConnection::getMessage() +{ + +} + + + +void NetConnection::queueMessage(const Message& message) +{ + +} + + + +void NetConnection::attemptConnection(TCPsocket& serverSocket) +{ + if(!connected) + { + socket=SDLNet_TCP_Accept(serverSocket); + if(!socket) + { + } + else + { + connected=true; + } + } +} + + diff -r 8e2a122cbd54 -r f1f468cdf724 src/NetConnection.h --- a/src/NetConnection.h Thu Apr 26 20:03:29 2007 -0400 +++ b/src/NetConnection.h Thu Apr 26 20:43:18 2007 -0400 @@ -23,11 +23,35 @@ ///It queues Message(s) it recieves from the connection. class NetConnection { +public: + ///Attempts to form a connection with the given address and the given port + NetConnection(const std::string& address, Uint16 port); + ///Initiates the NetConnection as blank + NetConnection(); + + ///Opens a new connection. Closes the current connection if nesseccarry. + void openConnection(const std::string& address, Uint16 port); + ///Closes the current connection. + void closeConnection(); + ///Returns true if this object is connected + bool isConnected(); + ///Pops the top-most message in the queue of messages. + ///When there are no messages, it will poll SDL for more packets. + Message getMessage(); + + ///Queues a message for sending to the connection. + void queueMessage(const Message& message); +protected: + ///This function attempts a connection using the provided TCP server socket. + ///One can use isConnected to test for success. + void attemptConnection(TCPsocket& serverSocket); - - +private: + IPaddress address; + TCPsocket socket; + bool connected; }; # HG changeset patch # User Bradley Arsenault # Date 1177636745 14400 # Node ID 5782c9a23ddcf5ac2d62d90acecfc772d28d7fd0 # Parent f1f468cdf724bce1d48dd6ef1db87c0c53f149b7 Inserted NetListener and interpolated with NetConnection. diff -r f1f468cdf724 -r 5782c9a23ddc src/NetConnection.cpp --- a/src/NetConnection.cpp Thu Apr 26 20:43:18 2007 -0400 +++ b/src/NetConnection.cpp Thu Apr 26 21:19:05 2007 -0400 @@ -28,7 +28,14 @@ NetConnection::NetConnection(const std:: NetConnection::NetConnection() { + connected = false; +} + + +NetConnection::~NetConnection() +{ + closeConnection(); } @@ -40,7 +47,7 @@ void NetConnection::openConnection(const //Resolve the address if(SDLNet_ResolveHost(&address, ipaddress.c_str(), port) == -1) { - printf("NetConnection::openConnection: %s\n", SDLNet_GetError()); + std::cout<<"NetConnection::openConnection:"< # Date 1177707963 14400 # Node ID fa0036e2b0441a4e74ddf78441c98a5e3afcf7e9 # Parent 5782c9a23ddcf5ac2d62d90acecfc772d28d7fd0 Added NetMessage class, for carrying messages, and its first derived class, NetSendOrder, to send Order(s) over the connection diff -r 5782c9a23ddc -r fa0036e2b044 src/NetMessage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/NetMessage.cpp Fri Apr 27 17:06:03 2007 -0400 @@ -0,0 +1,120 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "NetMessage.h" +#include +#include + +static NetMessage* NetMessage::getNetMessage(const Uint8 *netData, int dataLength) +{ + Uint8 netType = netData[0]; + NetMessage* message = NULL; + switch(netType) + { + case MNetSendOrder: + { + message = new NetSendOrder; + message->decodeData(netData, datalength); + } + break; + } + return message; +} + + +NetSendOrder::NetSendOrder() +{ + order=NULL; +} + + + +NetSendOrder::NetSendOrder(Order* newOrder) +{ + order=newOrder; +} + + + +void NetSendOrder::changeOrder(Order* newOrder) +{ + if(order!=NULL) + delete order; + order=newOrder; +} + + + +Order* NetSendOrder::getOrder() +{ + return order; +} + + + +Uint8 NetSendOrder::getMessageType() +{ + return MNetSendOrder; +} + + + +Uint8 *NetSendOrder::encodeData(void) +{ + Uint32 length = getDataLength(); + Uint8* data = new Uint8[length]; + data[0] = getMessageType(); + Uint8* orderData = order->getData(); + ///Copy the data from the order to the local copy + std::copy(orderData, orderData+length-1, data+1, data+length); + delete orderData; + return data; +} + + + +Uint32 NetSendOrder::getDataLength(void) +{ + return 1 + order->getDataLength(); +} + + + +bool NetSendOrder::decodeData(const Uint8 *data, int dataLength) +{ + Uint8 type = data[0]; + order = Order::getOrder(data+1, dataLength-1); +} + + + +std::string NetSendOrder::format() +{ + std::ostringstream s; + if(order==NULL) + { + s<<"NetSendOrder()"; + } + else + { + s<<"NetSendOrder(orderType="<type<<")"; + } + return s.str(); +} + + diff -r 5782c9a23ddc -r fa0036e2b044 src/NetMessage.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/NetMessage.h Fri Apr 27 17:06:03 2007 -0400 @@ -0,0 +1,104 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "SDL_net.h" +#include + + +///This is the enum of message types +enum NetMessageType +{ + MNetSendOrder, +}; + + + +///This is bassically a message in the Net Engine. A Message has two parts, +///a type and a body. The NetMessage base class also has a static function +///that will read data in, and create the appropriette derived class. +class NetMessage +{ +public: + ///Returns the message type + virtual Uint8 getMessageType() = 0; + + ///Reads the data, and returns an Order containing the data. + ///The Order may be casted to its particular subclass, using + ///the getMessageType function + static NetMessage* getNetMessage(const Uint8 *netData, int dataLength); + + ///Encodes the data into its shrunken, serialized form. It is important that + ///the first byte be the type returned from getMessageType. All + ///derived classes must follow this rule. + virtual Uint8 *encodeData(void)=0; + + ///Returns the length of the data that was encoded with the above function. + ///Derived classes must follow account for the messageType being the first + ///byte. + virtual Uint32 getDataLength(void)=0; + + ///Decodes data from the serialized form. Returns true on success, false otherwise. + ///The first byte is the type from getMessageType, and can be safely ignored by + ///derived classes, as it is handled by getNetMessage + virtual bool decodeData(const Uint8 *data, int dataLength)=0; + + ///This causes the message to be formated to a string, for debugging and/or logging + ///purposes + virtual std::string format()=0; + +}; + + + +///This message bassically wraps the Order class, meant to deliver an Order across a network. +class NetSendOrder : public NetMessage +{ +public: + ///Creates a NetSendOrder message with a NULL Order. + NetSendOrder(); + + ///Creates a NetSendOrder message with the provided Order. + ///This will assume ownership of the Order. + NetSendOrder(Order* newOrder); + + ///Changes the Order that NetSendOrder holds. This will + ///delete an Order that was already present. + void changeOrder(Order* newOrder); + + ///Returns the Order that NetSendOrder holds. + Order* getOrder(); + + ///Returns MNetSendOrder + Uint8 getMessageType(); + + ///Encodes the data, wraps the encoding of the Order + Uint8 *encodeData(void); + + ///Returns the data length + Uint32 getDataLength(void); + + ///Decodes the data, and reconstructs the Order. + bool decodeData(const Uint8 *data, int dataLength); + + ///Formats the NetSendOrder message with a small amount + ///of information. + std::string format(); + +private: + Order* order; +}; # HG changeset patch # User Bradley Arsenault # Date 1177734303 14400 # Node ID 66abec1732a68946ec7e9609eaf24d459c8b2cd5 # Parent fa0036e2b0441a4e74ddf78441c98a5e3afcf7e9 Implemented NetConnection in terms of NetMessage diff -r fa0036e2b044 -r 66abec1732a6 src/NetConnection.cpp --- a/src/NetConnection.cpp Fri Apr 27 17:06:03 2007 -0400 +++ b/src/NetConnection.cpp Sat Apr 28 00:25:03 2007 -0400 @@ -17,10 +17,13 @@ */ #include "NetConnection.h" +#include + NetConnection::NetConnection(const std::string& address, Uint16 port) { connected = false; + set=SDLNet_AllocSocketSet(1); openConnection(address, port); } @@ -28,6 +31,7 @@ NetConnection::NetConnection(const std:: NetConnection::NetConnection() { + set=SDLNet_AllocSocketSet(1); connected = false; } @@ -36,6 +40,12 @@ NetConnection::~NetConnection() NetConnection::~NetConnection() { closeConnection(); + SDLNet_FreeSocketSet(set); + while(!queue.empty()) + { + delete queue.top(); + queue.pop(); + } } @@ -47,7 +57,7 @@ void NetConnection::openConnection(const //Resolve the address if(SDLNet_ResolveHost(&address, ipaddress.c_str(), port) == -1) { - std::cout<<"NetConnection::openConnection:"< 0); + + //Check if there are messages in the queue. + //If so, return one, else, return NULL + if(!queue.size()) + { + NetMessage* message = queue.front(); + queue.pop(); + return message; + } + else + { + return NULL; + } } -void NetConnection::queueMessage(const Message& message) +void NetConnection::sendMessage(NetMessage* message) { - + if(connected) + { + Uint32 length = message.getDataLength(); + Uint8* data = message->encodeData(); + Uint8* newData = new Uint8[length+2]; + SDLNet_Write16(length, newData); + std::copy(data, data+length, newData+2, newData+2+length); + int result=SDLNet_TCP_Send(socket, data, length); + if(result class NetListener; @@ -43,12 +45,13 @@ public: ///Returns true if this object is connected bool isConnected(); - ///Pops the top-most message in the queue of messages. + ///Pops the top-most message in the queue of recieved messages. ///When there are no messages, it will poll SDL for more packets. - Message getMessage(); + ///The caller assumes ownership of the NetMessage. + NetMessage* getMessage(); - ///Queues a message for sending to the connection. - void queueMessage(const Message& message); + ///Sends a message across the connection. + void sendMessage(NetMessage* message); protected: friend class NetListener; @@ -59,5 +62,7 @@ private: private: IPaddress address; TCPsocket socket; + SDLNet_SocketSet set; bool connected; + std::queue recieved; }; diff -r fa0036e2b044 -r 66abec1732a6 src/NetMessage.cpp --- a/src/NetMessage.cpp Fri Apr 27 17:06:03 2007 -0400 +++ b/src/NetMessage.cpp Sat Apr 28 00:25:03 2007 -0400 @@ -76,19 +76,20 @@ Uint8 NetSendOrder::getMessageType() Uint8 *NetSendOrder::encodeData(void) { - Uint32 length = getDataLength(); + Uint16 length = getDataLength(); Uint8* data = new Uint8[length]; + Uint32 orderLength = order->getDataLength(); data[0] = getMessageType(); Uint8* orderData = order->getData(); ///Copy the data from the order to the local copy - std::copy(orderData, orderData+length-1, data+1, data+length); + std::copy(orderData, orderData+orderLength, data+1, data+length); delete orderData; return data; } -Uint32 NetSendOrder::getDataLength(void) +Uint16 NetSendOrder::getDataLength(void) { return 1 + order->getDataLength(); } diff -r fa0036e2b044 -r 66abec1732a6 src/NetMessage.h --- a/src/NetMessage.h Fri Apr 27 17:06:03 2007 -0400 +++ b/src/NetMessage.h Sat Apr 28 00:25:03 2007 -0400 @@ -49,8 +49,8 @@ public: ///Returns the length of the data that was encoded with the above function. ///Derived classes must follow account for the messageType being the first - ///byte. - virtual Uint32 getDataLength(void)=0; + ///byte. The length should not exceed 64 kilobytes. + virtual Uint16 getDataLength(void)=0; ///Decodes data from the serialized form. Returns true on success, false otherwise. ///The first byte is the type from getMessageType, and can be safely ignored by @@ -90,7 +90,7 @@ public: Uint8 *encodeData(void); ///Returns the data length - Uint32 getDataLength(void); + Uint16 getDataLength(void); ///Decodes the data, and reconstructs the Order. bool decodeData(const Uint8 *data, int dataLength); # HG changeset patch # User Bradley Arsenault # Date 1177967085 14400 # Node ID aa259b8af9352f94a65ab31e2cbfaefd10879ecf # Parent 66abec1732a68946ec7e9609eaf24d459c8b2cd5 Converted system to use boost::shared_ptr diff -r 66abec1732a6 -r aa259b8af935 src/NetConnection.cpp --- a/src/NetConnection.cpp Sat Apr 28 00:25:03 2007 -0400 +++ b/src/NetConnection.cpp Mon Apr 30 17:04:45 2007 -0400 @@ -41,11 +41,6 @@ NetConnection::~NetConnection() { closeConnection(); SDLNet_FreeSocketSet(set); - while(!queue.empty()) - { - delete queue.top(); - queue.pop(); - } } @@ -97,7 +92,7 @@ bool NetConnection::isConnected() -NetMessage* NetConnection::getMessage() +shared_ptr NetConnection::getMessage() { //Poll the SDL_net socket for more messages do @@ -119,7 +114,7 @@ NetMessage* NetConnection::getMessage() Uint8* data = new Uint8[length]; SDLNet_TCP_Recv(socket, data, length); //Now interpret the message from the data, and add it to the queue - NetMessage* message = NetMessage::getNetMessage(data, length); + shared_ptr message = NetMessage::getNetMessage(data, length); queue.push(message); } } while (numReady > 0); @@ -129,7 +124,7 @@ NetMessage* NetConnection::getMessage() //If so, return one, else, return NULL if(!queue.size()) { - NetMessage* message = queue.front(); + shared_ptr message = queue.front(); queue.pop(); return message; } @@ -141,7 +136,7 @@ NetMessage* NetConnection::getMessage() -void NetConnection::sendMessage(NetMessage* message) +void NetConnection::sendMessage(shared_ptr message) { if(connected) { @@ -157,6 +152,7 @@ void NetConnection::sendMessage(NetMessa closeConnection(); } delete data; + delete newData; } } diff -r 66abec1732a6 -r aa259b8af935 src/NetConnection.h --- a/src/NetConnection.h Sat Apr 28 00:25:03 2007 -0400 +++ b/src/NetConnection.h Mon Apr 30 17:04:45 2007 -0400 @@ -16,9 +16,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __NetConnection_h +#define __NetConnection_h + #include "SDL_net.h" #include "NetMessage.h" #include +#include + +using namespace boost; class NetListener; @@ -48,10 +54,10 @@ public: ///Pops the top-most message in the queue of recieved messages. ///When there are no messages, it will poll SDL for more packets. ///The caller assumes ownership of the NetMessage. - NetMessage* getMessage(); + shared_ptr getMessage(); ///Sends a message across the connection. - void sendMessage(NetMessage* message); + void sendMessage(shared_ptr message); protected: friend class NetListener; @@ -64,5 +70,8 @@ private: TCPsocket socket; SDLNet_SocketSet set; bool connected; - std::queue recieved; + std::queue > recieved; }; + + +#endif diff -r 66abec1732a6 -r aa259b8af935 src/NetListener.h --- a/src/NetListener.h Sat Apr 28 00:25:03 2007 -0400 +++ b/src/NetListener.h Mon Apr 30 17:04:45 2007 -0400 @@ -16,8 +16,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __NetListener_h +#define __NetListener_h + #include "SDL_net.h" #include "NetConnection.h" + +using namespace boost; ///NetListener represents a low level wrapper arround SDL. ///It listens for incoming connections. One should frequently @@ -52,3 +57,6 @@ private: TCPsocket socket; bool listening; }; + + +#endif diff -r 66abec1732a6 -r aa259b8af935 src/NetMessage.cpp --- a/src/NetMessage.cpp Sat Apr 28 00:25:03 2007 -0400 +++ b/src/NetMessage.cpp Mon Apr 30 17:04:45 2007 -0400 @@ -23,12 +23,12 @@ static NetMessage* NetMessage::getNetMes static NetMessage* NetMessage::getNetMessage(const Uint8 *netData, int dataLength) { Uint8 netType = netData[0]; - NetMessage* message = NULL; + shared_ptr message; switch(netType) { case MNetSendOrder: { - message = new NetSendOrder; + message.reset(new NetSendOrder); message->decodeData(netData, datalength); } break; diff -r 66abec1732a6 -r aa259b8af935 src/NetMessage.h --- a/src/NetMessage.h Sat Apr 28 00:25:03 2007 -0400 +++ b/src/NetMessage.h Mon Apr 30 17:04:45 2007 -0400 @@ -16,9 +16,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __NetMessage_h +#define __NetMessage_h + #include "SDL_net.h" #include +#include +using namespace boost; ///This is the enum of message types enum NetMessageType @@ -40,7 +45,7 @@ public: ///Reads the data, and returns an Order containing the data. ///The Order may be casted to its particular subclass, using ///the getMessageType function - static NetMessage* getNetMessage(const Uint8 *netData, int dataLength); + static sharded_ptr getNetMessage(const Uint8 *netData, int dataLength); ///Encodes the data into its shrunken, serialized form. It is important that ///the first byte be the type returned from getMessageType. All @@ -102,3 +107,6 @@ private: private: Order* order; }; + + +#endif # HG changeset patch # User Bradley Arsenault # Date 1177972045 14400 # Node ID bb6ed5af7a494c6f9443fc245906e1fe17c12786 # Parent aa259b8af9352f94a65ab31e2cbfaefd10879ecf Added basic unit tests for low level Net classes. diff -r aa259b8af935 -r bb6ed5af7a49 src/NetMessage.cpp --- a/src/NetMessage.cpp Mon Apr 30 17:04:45 2007 -0400 +++ b/src/NetMessage.cpp Mon Apr 30 18:27:25 2007 -0400 @@ -37,6 +37,14 @@ static NetMessage* NetMessage::getNetMes } + +bool NetMessage::operator!=(const NetMessage& rhs) const +{ + return !(*this == rhs); +} + + + NetSendOrder::NetSendOrder() { order=NULL; @@ -119,3 +127,21 @@ std::string NetSendOrder::format() } + +bool NetSendOrder::operator==(const NetMessage& rhs) const +{ + if(typeid(rhs)==typeid(NetSendOrder) + { + //Basic type comparison, since Order does not have good comparison facilities + const NetSendOrder& r = dynamic_cast(rhs); + if(order==NULL || rhs.order==NULL) + { + return order == rhs.order; + } + if(typeid(r.order) == typeid(order)) + { + return true; + } + } + return false; +} diff -r aa259b8af935 -r bb6ed5af7a49 src/NetMessage.h --- a/src/NetMessage.h Mon Apr 30 17:04:45 2007 -0400 +++ b/src/NetMessage.h Mon Apr 30 18:27:25 2007 -0400 @@ -66,6 +66,12 @@ public: ///purposes virtual std::string format()=0; + ///Compares two NetMessages. All derived Messages must implement this by + ///first testing to see if NetMessage casts to the derived class, and then + ///comparing internal data. + virtual bool operator==(const NetMessage& rhs)=0 const; + ///This does not need to be overloaded, but can be for efficiency purposes. + virtual bool operator!=(const NetMessage& rhs) const; }; @@ -104,6 +110,8 @@ public: ///of information. std::string format(); + ///Compares with another NetSendOrder + bool operator==(const NetMessage& rhs) const; private: Order* order; }; diff -r aa259b8af935 -r bb6ed5af7a49 src/NetTestSuite.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/NetTestSuite.cpp Mon Apr 30 18:27:25 2007 -0400 @@ -0,0 +1,125 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "NetTestSuite.h" + + +NetTestSuite::NetTestSuite() +{ + +} + + + + +int NetTestSuite::testNetMessages() +{ + ///The first few tests work with NetSendOrder + ///Test that the initial states of two NetSendOrder are the same + shared_ptr netSendOrder1 = new NetSendOrder; + shared_ptr netSendOrder2 = new NetSendOrder; + if((*netSendOrder1) != (*netSendOrder2)) + { + return 1; + } + ///Test that encoding and decoding a NetSendOrder will come out the same + netSendOrder1.changeOrder(new OrderDelete(1)); + Uint8* netSendOrderData = netSendOrder1.encodeData(); + shared_ptr decodedMessage = NetMessage::getNetMessage(netSendOrderData, netSendOrder1.getDataLength()); + delete netSendOrderData; + if((*netSendOrder1) != (*decodedMessage)) + { + return 2; + } +} + + + +int NetTestSuite::testListenerConnection() +{ + //Creates the NetListener at port 30 + NetListener nl(30); + //Creates a NetConnection representing the client + NetConnection nc_client; + nc_client.openConnection("localhost", 30); + //The server connection + NetConnection nc_server; + + //Causes NetListener to accept the connection + if(!nl.attemptConnection(nc_server)) + { + return 1; + } + //Checks if the connection was established on the client side + if(!nc_client.isConnected()) + { + return 2; + } + //Checks if the connection was established for the server side + if(!nc_server.isConnected()) + { + return 3; + } + + //Attempts to transmit a NetSendOrder over the connection + shared_ptr netSendOrder1 = new NetSendOrder; + netSendOrder1.changeOrder(new OrderDelete(1)); + nc_client.sendMessage(newSendOrder1); + //Recieves the message on the other end + shared_ptr netSendOrder2 = nc_server.getMessage(); + if(!netSendOrder2) + { + return 4; + } + //Makes sure the two are equal + if((*netSendOrder1) != (*netSendOrder2)) + { + return 5; + } +} + + + +bool NetTestSuite::runAllTests() +{ + std::cout<<"Running tests: "< + +using namespace boost; + +///This is a basic unit test system for the three low level net classes, +///NetConnection, NetListener, and NetMessage. +///When run, it is assumed that the host allows the program to listen on +//the port 30, and that it can connect to itself via localhost +class NetTestSuite +{ +public: + ///Constructor takes no arguments. + NetTestSuite(); + + ///Tests the various NetMessage classes. This makes sure + ///that the classes decode back to exactly what they where + ///encoded to. + int testNetMessages(); + + ///this tests NetListener and NetConnection in tandem. + int testListenerConnection(); + + ///Runs all of the tests. Outputs errors and failed tests to the console. + ///Returns true if all tests passed, false otherwise. + bool runAllTests(); +}; + + + + + + + + +#endif diff -r aa259b8af935 -r bb6ed5af7a49 src/YOGConsts.h --- a/src/YOGConsts.h Mon Apr 30 17:04:45 2007 -0400 +++ b/src/YOGConsts.h Mon Apr 30 18:27:25 2007 -0400 @@ -19,6 +19,22 @@ #ifndef __YOG_CONSTS_H #define __YOG_CONSTS_H + +///New YOG constants +const Uint16 YOG_SERVER_PORT = 7486; + + + + + + + + + + + + +/* #define YOG_SERVER_IP "yog.globulation2.org" #define YOG_SERVER_PORT 7486 @@ -129,5 +145,7 @@ enum YOGMessageType YMT_FLUSH_FILES=126, YMT_CLOSE_YOG=127 }; +*/ + #endif # HG changeset patch # User Bradley Arsenault # Date 1177975218 14400 # Node ID c726191f730924dd5f9b3d1ff9964113877f5a30 # Parent bb6ed5af7a494c6f9443fc245906e1fe17c12786 Frameworked YOG server and client diff -r bb6ed5af7a49 -r c726191f7309 src/YOGClient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/YOGClient.cpp Mon Apr 30 19:20:18 2007 -0400 @@ -0,0 +1,50 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "YOGClient.h" + + + +YOGClient::YOGClient(const std::string& server) +{ + connect(server); +} + + + +YOGClient::YOGClient() +{ + +} + + + +void YOGClient::connect(const std::string& server) +{ + nc.openConnection(server, YOG_SERVER_PORT); +} + + + +void YOGClient::update() +{ + +} + + + diff -r bb6ed5af7a49 -r c726191f7309 src/YOGClient.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/YOGClient.h Mon Apr 30 19:20:18 2007 -0400 @@ -0,0 +1,48 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __YOGClient_h +#define __YOGClient_h + +#include "NetMessage.h" +#include "NetConnection.h" +#include "NetListener.h" +#include "YOGConsts.h" + +///This represents the players YOG client, connecting to the YOG server. +class YOGClient +{ +public: + ///Initializes and attempts to connect to server. + YOGClient(const std::string& server); + + ///Initializes the client as empty + YOGClient(); + + ///Attempts a connection to server. + void connect(const std::string& server); + + ///Updates the client. This parses and interprets any incoming messages. + void update(); +private: + NetConnection& nc; +}; + + + +#endif diff -r bb6ed5af7a49 -r c726191f7309 src/YOGGameServer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/YOGGameServer.cpp Mon Apr 30 19:20:18 2007 -0400 @@ -0,0 +1,60 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "YOGGameServer.h" + + +YOGGameServer::YOGGameServer() +{ + nl.startListening(YOG_SERVER_PORT); +} + + + +void YOGGameServer::update() +{ + //First attempt connections with new players + shared_ptr nc = new NetConnection; + while(nl.attemptConnection(*nc)) + { + players.pushBack(YOGPlayer(nc)); + nc.reset(new NetConnection); + } + + //Call update to all of the players + for(std::list::iterator i=players.begin(); i!=players.end(); ++i) + { + i->update(); + } + + //Remove all of the players that have disconnected. + for(std::list::iterator i=players.begin(); i!=players.end();) + { + if(!i->isConnected()) + { + i = players.erase(i); + } + else + { + i++; + } + } +} + + + diff -r bb6ed5af7a49 -r c726191f7309 src/YOGGameServer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/YOGGameServer.h Mon Apr 30 19:20:18 2007 -0400 @@ -0,0 +1,56 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __YOGGameServer_h +#define __YOGGameServer_h + +#include "NetMessage.h" +#include "NetConnection.h" +#include "NetListener.h" +#include "YOGConsts.h" +#include "YOGPlayer.h" + +#include + +///This class encapsulates the YOG server. The YOG server is the games online server. +///There is one YOG server hosted by one of the project members. As well, each client +///is capable of hosting a YOG themselves, this technology is used for LAN games, +///and can also be used when a client decides to host a game themselves, which can +///reduce load on the project hosted server. For this, YOG has server redirection. +/// +///The YOG server has a few different behaviours. It can require passwords (for the +///project hosted YOG server), or allow anonymous connections (for LAN and client hosted +///games). It can maintain a list of games and the users that are in them (for the project +///server), or it can have one game, and all connected users are part of it (client hosted +///games). In this manner, the same YOG server is re-used for multiple purposes. +class YOGGameServer +{ +public: + ///Initiates the YOG Game Server and immeddiattely begins listening on the YOG port. + YOGGameServer(); + + ///This is the main update function. This must be called frequently (many times per + ///second) in order to give fast responce times and low latency for the users. + void update(); + +private: + NetListener listener; + std::list players; +}; + +#endif diff -r bb6ed5af7a49 -r c726191f7309 src/YOGPlayer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/YOGPlayer.cpp Mon Apr 30 19:20:18 2007 -0400 @@ -0,0 +1,38 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "YOGPlayer.h" + +YOGPlayer::YOGPlayer(shared_ptr connection) : connection(connection) +{ + +} + + + +void YOGPlayer::update() +{ + +} + + +bool YOGPlayer::isConnected() +{ + return connection.isConnected(); +} + diff -r bb6ed5af7a49 -r c726191f7309 src/YOGPlayer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/YOGPlayer.h Mon Apr 30 19:20:18 2007 -0400 @@ -0,0 +1,48 @@ +/* + Copyright (C) 2007 Bradley Arsenault + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __YOGPlayer_h +#define __YOGPlayer_h + +#include "YOGGameServer.h" +#include + +using namespace boost; + +///This represents a connected user on the YOG server. +class YOGPlayer +{ +public: + ///Establishes a YOGPlayer on the given connection. + YOGPlayer(shared_ptr connection); + + ///Updates the YOGPlayer. This deals with all incoming messages. + void update(); + + ///Returns true if this YOGPlayer is still connected + bool isConnected(); + +private: + shared_ptr connection; +}; + + + + + +#endif # HG changeset patch # User Bradley Arsenault # Date 1177986184 14400 # Node ID 897b12923a14450b1fab7c6cb035ea92d9388749 # Parent c726191f730924dd5f9b3d1ff9964113877f5a30 Added the first message (client version information) and frameworked the network state machine. diff -r c726191f7309 -r 897b12923a14 src/NetMessage.cpp --- a/src/NetMessage.cpp Mon Apr 30 19:20:18 2007 -0400 +++ b/src/NetMessage.cpp Mon Apr 30 22:23:04 2007 -0400 @@ -145,3 +145,68 @@ bool NetSendOrder::operator==(const NetM } return false; } + + + +NetSendClientInformation::NetSendClientInformation() +{ + versionMinor=VERSION_MINOR; +} + + + +Uint8 NetSendClientInformation::getMessageType() +{ + return MNetSendClientInformation; +} + + + +Uint8 *NetSendClientInformation::encodeData(void) +{ + Uint16 length = getDataLength(); + Uint8* data = new Uint8[length]; + //Write the version minor + SDLNet_Write8(length, versionMinor); + return data; +} + + + +Uint16 NetSendClientInformation::getDataLength(void) +{ + return 2; +} + + + +bool NetSendClientInformation::decodeData(const Uint8 *data, int dataLength) +{ + versionMinor = SDLNet_Read16(data); +} + + + +std::string NetSendClientInformation::format() +{ + std::ostringstream s; + s<<"NetSendClientInformation(versionMinor="<(rhs); + if(r.versionMinor == versionMinor) + { + return true; + } + } + return false; +} + diff -r c726191f7309 -r 897b12923a14 src/NetMessage.h --- a/src/NetMessage.h Mon Apr 30 19:20:18 2007 -0400 +++ b/src/NetMessage.h Mon Apr 30 22:23:04 2007 -0400 @@ -29,6 +29,7 @@ enum NetMessageType enum NetMessageType { MNetSendOrder, + MNetSendClientInformation, }; @@ -117,4 +118,33 @@ private: }; +///This message sends local version information to the server +class NetSendClientInformation : public NetMessage +{ +public: + ///Creates a NetSendClientInformation message + NetSendClientInformation(); + + ///Returns MNetSendClientInformation + Uint8 getMessageType(); + + ///Encodes the data, wraps the encoding of the Order + Uint8 *encodeData(void); + + ///Returns the data length + Uint16 getDataLength(void); + + ///Decodes the data, and reconstructs the Order. + bool decodeData(const Uint8 *data, int dataLength); + + ///Formats the NetSendClientInformation message with a small amount + ///of information. + std::string format(); + + ///Compares with another NetSendClientInformation + bool operator==(const NetMessage& rhs) const; +private: + Uint16 versionMinor; +}; + #endif diff -r c726191f7309 -r 897b12923a14 src/NetTestSuite.cpp --- a/src/NetTestSuite.cpp Mon Apr 30 19:20:18 2007 -0400 +++ b/src/NetTestSuite.cpp Mon Apr 30 22:23:04 2007 -0400 @@ -45,6 +45,16 @@ int NetTestSuite::testNetMessages() if((*netSendOrder1) != (*decodedMessage)) { return 2; + } + + ///Now, test NetSendClientInformation's serialization utilities + shared_ptr clientInfo1 = new NetSendClientInformation; + Uint8* clientInfoData = clientInfo1.encodeData(); + decodedMessage.reset(NetMessage::getNetMessage(clientInfoData, clientInfo1.getDataLength())); + delete clientInfoData; + if((*clientInfo1) != (*decodedMessage)) + { + return 3; } } diff -r c726191f7309 -r 897b12923a14 src/YOGClient.cpp --- a/src/YOGClient.cpp Mon Apr 30 19:20:18 2007 -0400 +++ b/src/YOGClient.cpp Mon Apr 30 22:23:04 2007 -0400 @@ -22,6 +22,7 @@ YOGClient::YOGClient(const std::string& server) { + connectionState = NotConnected; connect(server); } @@ -37,13 +38,25 @@ void YOGClient::connect(const std::strin void YOGClient::connect(const std::string& server) { nc.openConnection(server, YOG_SERVER_PORT); + connectionState = NeedToSendClientInformation; } void YOGClient::update() { - + //If we need to send client information, send it + if(connectionState == NeedToSendClientInformation) + { + shared_ptr message = new NetSendClientInformation; + nc.sendMessage(message); + connectionState == WaitingForServerInformation; + } + + + //Parse incoming messages. + shared_ptr message = nc.getMessage(); + Uint8 type = message->getMessageType(); } diff -r c726191f7309 -r 897b12923a14 src/YOGClient.h --- a/src/YOGClient.h Mon Apr 30 19:20:18 2007 -0400 +++ b/src/YOGClient.h Mon Apr 30 22:23:04 2007 -0400 @@ -41,6 +41,18 @@ public: void update(); private: NetConnection& nc; + ///This defines the current state of the connection. There are many states, + ///due to the asychronous design. + enum ConnectionState + { + //This signified unconnected. + NotConnected, + ///This is the starting state + NeedToSendClientInformation, + ///This means that the client is waiting to recieve server information + WaitingForServerInformation, + }; + Uint32 connectionState; }; diff -r c726191f7309 -r 897b12923a14 src/YOGPlayer.cpp --- a/src/YOGPlayer.cpp Mon Apr 30 19:20:18 2007 -0400 +++ b/src/YOGPlayer.cpp Mon Apr 30 22:23:04 2007 -0400 @@ -20,14 +20,22 @@ YOGPlayer::YOGPlayer(shared_ptr connection) : connection(connection) { - + connectionState = WaitingForClientInformation; } void YOGPlayer::update() { - + //Parse incoming messages. + shared_ptr message = nc.getMessage(); + Uint8 type = message->getMessageType(); + if(type==MNetSendClientInformation) + { + shared_ptr info = static_pointer_cast(message); + versionMinor = info->versionMinor; + connectionState = NeedToSendServerInformation; + } } diff -r c726191f7309 -r 897b12923a14 src/YOGPlayer.h --- a/src/YOGPlayer.h Mon Apr 30 19:20:18 2007 -0400 +++ b/src/YOGPlayer.h Mon Apr 30 22:23:04 2007 -0400 @@ -38,7 +38,18 @@ public: bool isConnected(); private: + enum + { + ///Means this is waiting for the client to send version information to the server. + WaitingForClientInformation, + ///Server information, such as the IRC server and server policies, needs to be sent + NeedToSendServerInformation. + }; + + Uint8 connectionState; + shared_ptr connection; + Uint16 versionMinor; }; # HG changeset patch # User Bradley Arsenault # Date 1178071459 14400 # Node ID 6c5cdf3de05f6dea4b702c33cce5369673ea0eff # Parent 897b12923a14450b1fab7c6cb035ea92d9388749 Improved NetMessage API for const-correctness. Fixed bug in NetSendClientInformation that did not send the message type at the begginning of encodeData. Created server information reply and server policies. Created login state machine, including 3 messages (attempt login, refuse login, accept login) and several changes to YOGPlayer, YOGClient, and YOGGameServer. Password encryption via RSA, and password stoarge on the server, are not yet implemented, and are planned after an encryption library decision can be finalized. diff -r 897b12923a14 -r 6c5cdf3de05f src/NetMessage.cpp --- a/src/NetMessage.cpp Mon Apr 30 22:23:04 2007 -0400 +++ b/src/NetMessage.cpp Tue May 01 22:04:19 2007 -0400 @@ -27,12 +27,25 @@ static NetMessage* NetMessage::getNetMes switch(netType) { case MNetSendOrder: - { - message.reset(new NetSendOrder); - message->decodeData(netData, datalength); - } - break; - } + message.reset(new NetSendOrder); + break; + case MNetSendClientInformation: + message.reset(new NetSendClientInformation); + break; + case MNetSendServerInformation: + message.reset(new NetSendServerInformation); + break; + case MNetAttemptLogin: + message.reset(new NetAttemptLogin); + break; + case MNetLoginSuccessful: + message.reset(new NetLoginSuccessful); + break; + case MNetRefuseLogin: + message.reset(new NetRefuseLogin); + break; + } + message->decodeData(netData, datalength); return message; } @@ -75,14 +88,14 @@ Order* NetSendOrder::getOrder() -Uint8 NetSendOrder::getMessageType() +Uint8 NetSendOrder::getMessageType() const { return MNetSendOrder; } -Uint8 *NetSendOrder::encodeData(void) +Uint8 *NetSendOrder::encodeData() const { Uint16 length = getDataLength(); Uint8* data = new Uint8[length]; @@ -97,7 +110,7 @@ Uint8 *NetSendOrder::encodeData(void) -Uint16 NetSendOrder::getDataLength(void) +Uint16 NetSendOrder::getDataLength() const { return 1 + order->getDataLength(); } @@ -112,7 +125,7 @@ bool NetSendOrder::decodeData(const Uint -std::string NetSendOrder::format() +std::string NetSendOrder::format() const { std::ostringstream s; if(order==NULL) @@ -130,9 +143,8 @@ std::string NetSendOrder::format() bool NetSendOrder::operator==(const NetMessage& rhs) const { - if(typeid(rhs)==typeid(NetSendOrder) - { - //Basic type comparison, since Order does not have good comparison facilities + if(typeid(rhs)==typeid(NetSendOrder)) + { const NetSendOrder& r = dynamic_cast(rhs); if(order==NULL || rhs.order==NULL) { @@ -155,39 +167,41 @@ NetSendClientInformation::NetSendClientI -Uint8 NetSendClientInformation::getMessageType() +Uint8 NetSendClientInformation::getMessageType() const { return MNetSendClientInformation; } -Uint8 *NetSendClientInformation::encodeData(void) -{ - Uint16 length = getDataLength(); - Uint8* data = new Uint8[length]; +Uint8 *NetSendClientInformation::encodeData() const +{ + Uint16 length = getDataLength(); + Uint8* data = new Uint8[length]; + data[0] = getMessageType(); //Write the version minor - SDLNet_Write8(length, versionMinor); - return data; -} - - - -Uint16 NetSendClientInformation::getDataLength(void) -{ - return 2; + SDLNet_Write16(data+1, versionMinor); + return data; +} + + + +Uint16 NetSendClientInformation::getDataLength() const +{ + return 3; } bool NetSendClientInformation::decodeData(const Uint8 *data, int dataLength) { - versionMinor = SDLNet_Read16(data); -} - - - -std::string NetSendClientInformation::format() + Uint8 type = data[0]; + versionMinor = SDLNet_Read16(data+1); +} + + + +std::string NetSendClientInformation::format() const { std::ostringstream s; s<<"NetSendClientInformation(versionMinor="<(rhs); if(r.versionMinor == versionMinor) { @@ -210,3 +223,366 @@ bool NetSendClientInformation::operator= return false; } + +Uint63 NetSendClientInformation::getVersionMinor() const +{ + return versionMinor; +} + + + +NetSendServerInformation::NetSendServerInformation(YOGLoginPolicy loginPolicy, YOGGamePolicy gamePolicy) + : loginPolicy(loginPolicy), gamePolicy(gamePolicy) +{ + +} + + + +NetSendServerInformation::NetSendServerInformation() + : loginPolicy(YOGRequirePassword), gamePolicy(YOGSingleGame) +{ + +} + + + +Uint8 NetSendServerInformation::getMessageType() const +{ + return MNetSendServerInformation; +} + + + +Uint8 *NetSendServerInformation::encodeData() const +{ + Uint16 length = getDataLength(); + Uint8* data = new Uint8[length]; + data[0] = getMessageType(); + //Write the policy information + data[1] = static_cast(loginPolicy); + data[2] = static_cast(gamePolicy); + return data; +} + + + +Uint16 NetSendServerInformation::getDataLength() const +{ + return 3; +} + + + +bool NetSendServerInformation::decodeData(const Uint8 *data, int dataLength) +{ + Uint8 type = data[0]; + loginPolicy = data[1]; + gamePolicy = data[2]; +} + + + +std::string NetSendServerInformation::format() const +{ + std::ostringstream s; + s<<"NetSendServerInformation("; + if(loginPolicy == YOGRequirePassword) + s<<"loginPolicy=YOGRequirePassword; "; + else if(loginPolicy == YOGAnonymousLogin) + s<<"loginPolicy=YOGAnonymousLogin; "; + + if(gamePolicy == YOGSingleGame) + s<<"gamePolicy=YOGSingleGame; "; + else if(gamePolicy == YOGMultipleGames) + s<<"gamePolicy=YOGMultipleGames; "; + + s<<")"; + return s.str(); +} + + + +bool NetSendServerInformation::operator==(const NetMessage& rhs) const +{ + if(typeid(rhs)==typeid(NetSendServerInformation)) + { + const NetSendServerInformation& r = dynamic_cast(rhs); + if(r.loginPolicy == loginPolicy && r.gamePolicy == gamePolicy) + { + return true; + } + } + return false; +} + + + +YOGLoginPolicy NetSendServerInformation::getLoginPolicy() const +{ + return loginPolicy; +} + + + +YOGGamePolicy NetSendServerInformation::getGamePolicy() const +{ + return gamePolicy; +} + + + +NetAttemptLogin::NetAttemptLogin(const std::string& username, const std::string& password) + : username(username), password(password) +{ + +} + + + +NetAttemptLogin::NetAttemptLogin() +{ + +} + + + +Uint8 NetAttemptLogin::getMessageType() const +{ + return MNetAttemptLogin; +} + + + +Uint8 *NetAttemptLogin::encodeData() const +{ + Uint16 length = getDataLength(); + Uint8* data = new Uint8[length]; + //Use pos to keep track of the position in the data + Uint8 pos = 0; + data[pos] = getMessageType(); + pos+=1; + //Write the username. + data[pos] = static_cast(username.size()); + pos+=1; + std::copy(username.begin(), username.end(), data+pos); + pos+=username.size(); + //Write the password + data[pos] = static_cast(password.size()); + pos+=1; + std::copy(password.begin(), password.end(), data+pos); + pos+=password.size(); + return data; +} + + + +Uint16 NetAttemptLogin::getDataLength() const +{ + return 3 + username.size() + password.size(); +} + + + +bool NetAttemptLogin::decodeData(const Uint8 *data, int dataLength) +{ + Uint8 pos = 0; + Uint8 type = data[pos]; + pos+=1; + + //Read in the username + Uint8 usernameLength = data[pos]; + pos+=1; + for(int i=0; i(data[pos]); + pos+=1; + } + + //Read in the password + Uint8 passwordLength = data[pos]; + pos+=1; + for(int i=0; i(data[pos]); + pos+=1; + } +} + + + +std::string NetAttemptLogin::format() const +{ + std::ostringstream s; + s<<"NetAttemptLogin("<<"username="<(rhs); + if(r.username == username && r.password==password) + { + return true; + } + } + return false; +} + + + +const std::string& NetAttemptLogin::getUsername() const +{ + return username; +} + + + +const std::string& NetAttemptLogin::getPassword() const +{ + return password; +} + + + +NetLoginSuccessful::NetLoginSuccessful() +{ + +} + + + +Uint8 NetLoginSuccessful::getMessageType() const +{ + return MNetLoginSuccessful; +} + + + +Uint8 *NetLoginSuccessful::encodeData() const +{ + Uint16 length = getDataLength(); + Uint8* data = new Uint8[length]; + data[0] = getMessageType(); + return data; +} + + + +Uint16 NetLoginSuccessful::getDataLength() const +{ + return 1; +} + + + +bool NetLoginSuccessful::decodeData(const Uint8 *data, int dataLength) +{ + Uint8 type = data[0]; +} + + + +std::string NetLoginSuccessful::format() const +{ + std::ostringstream s; + s<<"NetLoginSuccessful()"; + return s.str(); +} + + + +bool NetLoginSuccessful::operator==(const NetMessage& rhs) const +{ + if(typeid(rhs)==typeid(NetLoginSuccessful)) + { + const NetLoginSuccessful& r = dynamic_cast(rhs); + return true; + } + return false; +} + + +NetRefuseLogin::NetRefuseLogin() + : reason(YOGLoginSuccessful) +{ + +} + + + +NetRefuseLogin::NetRefuseLogin(YOGLoginState reason) + : reason(reason) +{ + +} + + + +Uint8 NetRefuseLogin::getMessageType() const +{ + return MNetRefuseLogin; +} + + + +Uint8 *NetRefuseLogin::encodeData() const +{ + Uint16 length = getDataLength(); + Uint8* data = new Uint8[length]; + data[0] = getMessageType(); + data[1] = static_cast(reason); + return data; +} + + + +Uint16 NetRefuseLogin::getDataLength() const +{ + return 2; +} + + + +bool NetRefuseLogin::decodeData(const Uint8 *data, int dataLength) +{ + Uint8 type = data[0]; + reason = data[1]; +} + + + +std::string NetRefuseLogin::format() const +{ + std::ostringstream s; + s<<"NetRefuseLogin(reason="<(rhs); + if(r.reason == reason) + { + return true; + } + } + return false; +} + + + +YOGLoginState NetRefuseLogin::getRefusalReason() const +{ + return reason; +} + + diff -r 897b12923a14 -r 6c5cdf3de05f src/NetMessage.h --- a/src/NetMessage.h Mon Apr 30 22:23:04 2007 -0400 +++ b/src/NetMessage.h Tue May 01 22:04:19 2007 -0400 @@ -22,6 +22,7 @@ #include "SDL_net.h" #include #include +#include "YOGConsts.h" using namespace boost; @@ -30,8 +31,11 @@ enum NetMessageType { MNetSendOrder, MNetSendClientInformation, -}; - + MNetSendServerInformation, + MNetAttemptLogin, + MNetLoginSuccessful, + MNetRefuseLogin, +}; ///This is bassically a message in the Net Engine. A Message has two parts, @@ -40,8 +44,11 @@ class NetMessage class NetMessage { public: + ///Virtual destructor for derived classes + virtual ~NetMessage() {} + ///Returns the message type - virtual Uint8 getMessageType() = 0; + virtual Uint8 getMessageType() const = 0; ///Reads the data, and returns an Order containing the data. ///The Order may be casted to its particular subclass, using @@ -51,26 +58,26 @@ public: ///Encodes the data into its shrunken, serialized form. It is important that ///the first byte be the type returned from getMessageType. All ///derived classes must follow this rule. - virtual Uint8 *encodeData(void)=0; + virtual Uint8 *encodeData() const = 0; ///Returns the length of the data that was encoded with the above function. ///Derived classes must follow account for the messageType being the first ///byte. The length should not exceed 64 kilobytes. - virtual Uint16 getDataLength(void)=0; + virtual Uint16 getDataLength() const = 0; ///Decodes data from the serialized form. Returns true on success, false otherwise. ///The first byte is the type from getMessageType, and can be safely ignored by ///derived classes, as it is handled by getNetMessage - virtual bool decodeData(const Uint8 *data, int dataLength)=0; + virtual bool decodeData(const Uint8 *data, int dataLength) = 0; ///This causes the message to be formated to a string, for debugging and/or logging ///purposes - virtual std::string format()=0; + virtual std::string format() const = 0 ; ///Compares two NetMessages. All derived Messages must implement this by ///first testing to see if NetMessage casts to the derived class, and then ///comparing internal data. - virtual bool operator==(const NetMessage& rhs)=0 const; + virtual bool operator==(const NetMessage& rhs) = 0 const; ///This does not need to be overloaded, but can be for efficiency purposes. virtual bool operator!=(const NetMessage& rhs) const; }; @@ -96,26 +103,27 @@ public: Order* getOrder(); ///Returns MNetSendOrder - Uint8 getMessageType(); + Uint8 getMessageType() const; ///Encodes the data, wraps the encoding of the Order - Uint8 *encodeData(void); - - ///Returns the data length - Uint16 getDataLength(void); + Uint8 *encodeData() const; + + ///Returns the data length + Uint16 getDataLength() const; ///Decodes the data, and reconstructs the Order. bool decodeData(const Uint8 *data, int dataLength); ///Formats the NetSendOrder message with a small amount ///of information. - std::string format(); + std::string format() const; ///Compares with another NetSendOrder bool operator==(const NetMessage& rhs) const; private: Order* order; }; + ///This message sends local version information to the server @@ -126,25 +134,180 @@ public: NetSendClientInformation(); ///Returns MNetSendClientInformation - Uint8 getMessageType(); - - ///Encodes the data, wraps the encoding of the Order - Uint8 *encodeData(void); - - ///Returns the data length - Uint16 getDataLength(void); - - ///Decodes the data, and reconstructs the Order. + Uint8 getMessageType() const; + + ///Encodes the data + Uint8 *encodeData() const; + + ///Returns the data length + Uint16 getDataLength() const; + + ///Decodes the data bool decodeData(const Uint8 *data, int dataLength); ///Formats the NetSendClientInformation message with a small amount ///of information. - std::string format(); + std::string format() const; ///Compares with another NetSendClientInformation bool operator==(const NetMessage& rhs) const; + + ///Returns the version minor + Uint63 getVersionMinor() const; private: Uint16 versionMinor; }; + + +///This message sends server information to the client. This includes +///login and game policies (for example anonymous / password required login) +class NetSendServerInformation : public NetMessage +{ +public: + ///Creates a NetSendServerInformation message with the provided server information + NetSendServerInformation(YOGLoginPolicy loginPolicy, YOGGamePolicy gamePolicy); + + ///Creates an empty NetSendServerInformation message + NetSendServerInformation(); + + ///Returns MNetSendServerInformation + Uint8 getMessageType() const; + + ///Encodes the data + Uint8 *encodeData() const; + + ///Returns the data length + Uint16 getDataLength() const; + + ///Decodes the data + bool decodeData(const Uint8 *data, int dataLength); + + ///Formats the NetSendServerInformation message with a small amount + ///of information. + std::string format() const; + + ///Compares with another NetSendServerInformation + bool operator==(const NetMessage& rhs) const; + + ///Returns the login policy + YOGLoginPolicy getLoginPolicy() const; + + ///Returns the game policy + YOGGamePolicy getGamePolicy() const; + +private: + YOGLoginPolicy loginPolicy; + YOGGamePolicy gamePolicy; +}; + + + +///This message sends login information (username and password) to the server. +class NetAttemptLogin : public NetMessage +{ +public: + ///Creates a NetAttemptLogin message with the given username and password + NetAttemptLogin(const std::string& username, const std::string& password); + + ///Creates an empty NetAttemptLogin message + NetAttemptLogin(); + + ///Returns MNetAttemptLogin + Uint8 getMessageType() const; + + ///Encodes the data + Uint8 *encodeData() const; + + ///Returns the data length + Uint16 getDataLength() const; + + ///Decodes the data + bool decodeData(const Uint8 *data, int dataLength); + + ///Formats the NetAttemptLogin message with a small amount + ///of information. + std::string format() const; + + ///Compares with another NetAttemptLogin + bool operator==(const NetMessage& rhs) const; + + ///Returns the username + const std::string& getUsername() const; + + ///Returns the password + const std::string& getPassword() const; + +private: + std::string username; + std::string password; +}; + + + +///This message informs the client its login was successfull +class NetLoginSuccessful : public NetMessage +{ +public: + ///Creates a NetLoginSuccessful message + NetLoginSuccessful(); + + ///Returns MNetLoginSuccessful + Uint8 getMessageType() const; + + ///Encodes the data, however, this message has no data, it must be atleast one byte. + Uint8 *encodeData() const; + + ///Returns the data length of 1 + Uint16 getDataLength() const; + + ///Decodes the data. + bool decodeData(const Uint8 *data, int dataLength); + + ///Formats the NetLoginSuccessful message with a small amount + ///of information. + std::string format() const; + + ///Compares with another NetLoginSuccessful + bool operator==(const NetMessage& rhs) const; +}; + + + +///This message informs the client its login was refused. It carries with it the reason why. +class NetRefuseLogin : public NetMessage +{ +public: + ///Creates an empty NetRefuseLogin message + NetRefuseLogin(); + + ///Creates a NetRefuseLogin message with the given reason + NetRefuseLogin(YOGLoginState reason); + + ///Returns MNetRefuseLogin + Uint8 getMessageType() const; + + ///Encodes the data, however, this message has no data, it must be atleast one byte. + Uint8 *encodeData() const; + + ///Returns the data length of 1 + Uint16 getDataLength() const; + + ///Decodes the data. + bool decodeData(const Uint8 *data, int dataLength); + + ///Formats the NetRefuseLogin message with a small amount + ///of information. + std::string format() const; + + ///Compares with another NetRefuseLogin + bool operator==(const NetMessage& rhs) const; + + ///Returns the reason why this login was refused + YOGLoginState getRefusalReason() const; +private: + YOGLoginState reason; +}; + + #endif diff -r 897b12923a14 -r 6c5cdf3de05f src/YOGClient.cpp --- a/src/YOGClient.cpp Mon Apr 30 22:23:04 2007 -0400 +++ b/src/YOGClient.cpp Tue May 01 22:04:19 2007 -0400 @@ -23,6 +23,9 @@ YOGClient::YOGClient(const std::string& YOGClient::YOGClient(const std::string& server) { connectionState = NotConnected; + loginPolicy = YOGUnknownLoginPolicy; + gamePolicy = YOGUnknownGamePolicy; + loginState = YOGLoginUnknown; connect(server); } @@ -52,12 +55,69 @@ void YOGClient::update() nc.sendMessage(message); connectionState == WaitingForServerInformation; } - - + + //Parse incoming messages. shared_ptr message = nc.getMessage(); Uint8 type = message->getMessageType(); + //This recieves the server information + if(type==MNetSendServerInformation) + { + shared_ptr info = static_pointer_cast(message); + loginPolicy = info->getLoginPolicy(); + gamePolicy = info->getGamePolicy(); + connectionState = WaitingForLoginInformation; + } + //This recieves a login acceptance message + if(type==MNetLoginSuccessful) + { + shared_ptr info = static_pointer_cast(message); + connectionState = WaitingForGameList; + loginState = YOGLoginSuccessful; + } + //This recieves a login refusal message + if(type==MNetRefuseLogin) + { + shared_ptr info = static_pointer_cast(message); + connectionState = WaitingForLoginInformation; + loginState = info->getRefusalReason(); + } } +ConnectionState YOGClient::getConnectionState() const +{ + return connectionState; +} + + + +YOGLoginPolicy YOGClient::getLoginPolicy() const +{ + return loginPolicy; +} + + + +YOGGamePolicy YOGClient::getGamePolicy() const +{ + return gamePolicy; +} + + + +void YOGClient::attemptLogin(const std::string& username, const std::string& password) +{ + shared_ptr message = new NetAttemptLogin(username, password); + nc.sendMessage(message); + connectionState = WaitingForLoginReply; +} + + +YOGLoginState YOGClient::getLoginState() const +{ + return loginState; +} + + diff -r 897b12923a14 -r 6c5cdf3de05f src/YOGClient.h --- a/src/YOGClient.h Mon Apr 30 22:23:04 2007 -0400 +++ b/src/YOGClient.h Tue May 01 22:04:19 2007 -0400 @@ -39,8 +39,7 @@ public: ///Updates the client. This parses and interprets any incoming messages. void update(); -private: - NetConnection& nc; + ///This defines the current state of the connection. There are many states, ///due to the asychronous design. enum ConnectionState @@ -51,8 +50,47 @@ private: NeedToSendClientInformation, ///This means that the client is waiting to recieve server information WaitingForServerInformation, + ///This means that the YOGClient is waiting for an external force to send + ///login information to the YOGClient. This would usually be the GUI that + ///is managing it. + WaitingForLoginInformation, + ///This means that the client is waiting for a reply from a login attempt. + WaitingForLoginReply, + ///This means that the client is waiting for a game list to be sent + WaitingForGameList, }; + + ///This returns the current connection state. This state includes both internal and external + ConnectionState getConnectionState() const; + + ///This will return the current login policy used by the server, if its known. + ///When unknown, this will return YOGUnknownLoginPolicy + YOGLoginPolicy getLoginPolicy() const; + + ///This will return the current game policy used by the server, if its known. + ///When unknown, this will return YOGUnknownGamePolicy + YOGGamePolicy getGamePolicy() const; + + ///This will attempt a login with the provided login information. The password is not + ///mandatory. If the login policy is YOGAnonymousLogin, then the password will simply + ///be ignored. Login attempts should be done when the client is in the + ///WaitingForLoginInformation state. + void attemptLogin(const std::string& username, const std::string& password = ""); + + ///This will return the login state. When this is unknown (it hasn't recieved a reply + ///yet), this returns YOGLoginUnknown. In the case when there has been multiple + ///attempts at a login, this returns the state of the most recent attempt that has + ///gotten a reply. + YOGLoginState getLoginState() const; + +private: + NetConnection& nc; + Uint32 connectionState; + + YOGLoginPolicy loginPolicy; + YOGGamePolicy gamePolicy; + YOGLoginState loginState; }; diff -r 897b12923a14 -r 6c5cdf3de05f src/YOGConsts.h --- a/src/YOGConsts.h Mon Apr 30 22:23:04 2007 -0400 +++ b/src/YOGConsts.h Tue May 01 22:04:19 2007 -0400 @@ -23,10 +23,48 @@ ///New YOG constants const Uint16 YOG_SERVER_PORT = 7486; +///Policies for login +enum YOGLoginPolicy +{ + ///This represents an unknown policy. Used by the client + ///before the policy information has been transferred across the network + YOGUnknownLoginPolicy, + ///This policy demands a password with the login + YOGRequirePassword, + ///This policy allows anonymous logins. + YOGAnonymousLogin, +}; +///Policies for the games the server hosts +enum YOGGamePolicy +{ + ///This represents an unknown policy. Used by the client + ///before the policy information has been transferred across the network + YOGUnknownGamePolicy, + ///In this policy, the server hosts one game, and all connected are a part of it. + YOGSingleGame, + ///In this policy, the server hosts multiple games, and users can choose what game + ///they are a part of + YOGMultipleGames, +}; - - +///Represents the state of a login. Whether it was accepted, or if it +///was refused, and if so, for what reason. +enum YOGLoginState +{ + ///This represents when the login was successful. + YOGLoginSuccessful, + ///This represents when the login state is unknown + YOGLoginUnknown, + ///This means that the password was incorrect. + ///(only for servers that require registration) + YOGPasswordIncorrect, + ///This means that a user with the same username is already connected. + YOGUsernameAlreadyUsed, + ///This means that no registered user with that username exists + ///(only for servers that require registration) + YOGUserNotRegistered, +}; diff -r 897b12923a14 -r 6c5cdf3de05f src/YOGGameServer.cpp --- a/src/YOGGameServer.cpp Mon Apr 30 22:23:04 2007 -0400 +++ b/src/YOGGameServer.cpp Tue May 01 22:04:19 2007 -0400 @@ -19,7 +19,8 @@ #include "YOGGameServer.h" -YOGGameServer::YOGGameServer() +YOGGameServer::YOGGameServer(YOGLoginPolicy loginPolicy, YOGGamePolicy gamePolicy) + : loginPolicy(loginPolicy), gamePolicy(gamePolicy) { nl.startListening(YOG_SERVER_PORT); } @@ -58,3 +59,23 @@ void YOGGameServer::update() +YOGLoginPolicy YOGGameServer::getLoginPolicy() const +{ + return loginPolicy; +} + + + +YOGGamePolicy YOGGameServer::getGamePolicy() const +{ + return gamePolicy; +} + + + +YOGLoginState YOGGameServer::verifyLoginInformation(const std::string& username, const std::string& password) +{ + ///Doesn't do anything yet. + return YOGLoginSuccessful; +} + diff -r 897b12923a14 -r 6c5cdf3de05f src/YOGGameServer.h --- a/src/YOGGameServer.h Mon Apr 30 22:23:04 2007 -0400 +++ b/src/YOGGameServer.h Tue May 01 22:04:19 2007 -0400 @@ -42,15 +42,26 @@ class YOGGameServer { public: ///Initiates the YOG Game Server and immeddiattely begins listening on the YOG port. - YOGGameServer(); + YOGGameServer(YOGLoginPolicy loginPolicy, YOGGamePolicy gamePolicy); ///This is the main update function. This must be called frequently (many times per ///second) in order to give fast responce times and low latency for the users. void update(); + ///Returns the login policy that is being used by the server + YOGLoginPolicy getLoginPolicy() const; + + ///Returns the game policy that is being used by the server + YOGGamePolicy getGamePolicy() const; + + ///Returns whether the users password is correct. + YOGLoginState verifyLoginInformation(const std::string& username, const std::string& password); + private: NetListener listener; std::list players; + YOGLoginPolicy loginPolicy; + YOGGamePolicy gamePolicy; }; #endif diff -r 897b12923a14 -r 6c5cdf3de05f src/YOGPlayer.cpp --- a/src/YOGPlayer.cpp Mon Apr 30 22:23:04 2007 -0400 +++ b/src/YOGPlayer.cpp Tue May 01 22:04:19 2007 -0400 @@ -21,20 +21,62 @@ YOGPlayer::YOGPlayer(shared_ptr connection) : connection(connection) { connectionState = WaitingForClientInformation; + refusalReason = YOGLoginSuccessful; } -void YOGPlayer::update() +void YOGPlayer::update(YOGGameServer& server) { //Parse incoming messages. shared_ptr message = nc.getMessage(); Uint8 type = message->getMessageType(); + //This recieves the client information if(type==MNetSendClientInformation) { shared_ptr info = static_pointer_cast(message); - versionMinor = info->versionMinor; + versionMinor = info->getVersionMinor(); connectionState = NeedToSendServerInformation; + } + //This recieves a login attempt + else if(type==MNetAttemptLogin) + { + shared_ptr info = static_pointer_cast(message); + std::string username = info->getUsername(); + std::string password = info->getPassword(); + loginState = server.verifyLoginInformation(username, password); + if(refusalReason == YOGLoginSuccessful) + { + connectionState = NeedToSendLoginAccepted; + } + else + { + connectionState = NeedToSendLoginRefusal; + } + } + + + //Send outgoing messages + //Send the server information + if(connectionState==NeedToSendServerInformation) + { + shared_ptr info = new NetSendServerInformation(server.getLoginPolicy(), server.getGamePolicy()); + connection->sendMessage(info); + connectionState = WaitingForLoginAttempt; + } + //Send the login accepted message + if(connectionState==NeedToSendLoginAccepted) + { + shared_ptr accepted = new NetLoginSuccessful; + connection->sendMessage(accepted); + connectionState = NeedToSendGameList; + } + //Send the login refused message + if(connectionState==NeedToSendLoginRefusal) + { + shared_ptr refused = new NetRefuseLogin(loginState); + connection->sendMessage(refused); + connectionState = WaitingForLoginAttempt; } } diff -r 897b12923a14 -r 6c5cdf3de05f src/YOGPlayer.h --- a/src/YOGPlayer.h Mon Apr 30 22:23:04 2007 -0400 +++ b/src/YOGPlayer.h Tue May 01 22:04:19 2007 -0400 @@ -32,24 +32,34 @@ public: YOGPlayer(shared_ptr connection); ///Updates the YOGPlayer. This deals with all incoming messages. - void update(); + void update(YOGGameServer& server); ///Returns true if this YOGPlayer is still connected bool isConnected(); private: + ///This enum represents the state machine of a connection. enum { ///Means this is waiting for the client to send version information to the server. WaitingForClientInformation, ///Server information, such as the IRC server and server policies, needs to be sent - NeedToSendServerInformation. + NeedToSendServerInformation, + ///Means its waiting for a login attempt by the client. + WaitingForLoginAttempt, + ///A login accceptance needs to be sent + NeedToSendLoginAccepted, + ///A login refusal needs to be sent + NeedToSendLoginRefusal, + ///Game list information needs to be sent + NeedToSendGameList, }; Uint8 connectionState; shared_ptr connection; Uint16 versionMinor; + YOGLoginState loginState; };