From d55f2bd017a11c5eaf0c6150221ac51c75042830 Mon Sep 17 00:00:00 2001 From: cvsguest Date: Fri, 7 Nov 2003 23:38:18 +0000 Subject: [PATCH] Multiplayer client/server system changes and new files --- configure.ac | 15 ++++ src/Main/Makefile.am | 18 ++++- src/Makefile.am | 7 ++ src/Server/Makefile.am | 36 +++++++++ src/Server/buftest.cxx | 74 ++++++++++++++++++ src/Server/message.cxx | 34 +++++++++ src/Server/message.hxx | 83 ++++++++++++++++++++ src/Server/messagebuf.cxx | 137 ++++++++++++++++++++++++++++++++++ src/Server/messagebuf.hxx | 92 +++++++++++++++++++++++ src/Server/msg_0001_hello.cxx | 37 +++++++++ src/Server/msg_0001_hello.hxx | 48 ++++++++++++ src/Server/msgtest.cxx | 6 ++ 12 files changed, 586 insertions(+), 1 deletion(-) create mode 100644 src/Server/Makefile.am create mode 100644 src/Server/buftest.cxx create mode 100644 src/Server/message.cxx create mode 100644 src/Server/message.hxx create mode 100644 src/Server/messagebuf.cxx create mode 100644 src/Server/messagebuf.hxx create mode 100644 src/Server/msg_0001_hello.cxx create mode 100644 src/Server/msg_0001_hello.hxx create mode 100644 src/Server/msgtest.cxx diff --git a/configure.ac b/configure.ac index 490ddecf8..daacc73eb 100644 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,16 @@ fi AM_CONDITIONAL(ENABLE_NETWORK_OLK, test "x$with_network_olk" != "xno" -a "x$with_multiplayer" = "xno") AM_CONDITIONAL(ENABLE_MPLAYER_AS, test "x$with_multiplayer" != "xno") +AC_ARG_WITH(multiserver, [ --with-multiserver Include multiplayer client/server support]) + +if test "x$with_multiserver" = "xno"; then + echo "Building without multiplayer client/server support" +else + echo "Building with multiplayer client/server support" + AC_DEFINE([FG_MSERVER_AS], 1, [Define to build with multiplayer client/server support]) +fi + +AM_CONDITIONAL(ENABLE_MSERVER_AS, test "x$with_multiserver" != "xno") # Specify if we want to use WeatherCM instead of FGEnvironment. # default to with_weathercm=no @@ -546,6 +556,7 @@ AC_CONFIG_FILES([ \ src/Replay/Makefile \ src/Scenery/Makefile \ src/Scripting/Makefile \ + src/Server/Makefile \ src/Sound/Makefile \ src/Systems/Makefile \ src/Time/Makefile \ @@ -595,6 +606,10 @@ elif test "x$with_network_olk" != "xno"; then echo "Using Oliver's multi-pilot network support" fi +if test "x$with_multiserver" != "xno"; then + echo "Using multiplayer client/server support" +fi + if test "x$with_threads" = "xyes"; then echo "threads: yes" else diff --git a/src/Main/Makefile.am b/src/Main/Makefile.am index a5492ddb0..36447d542 100644 --- a/src/Main/Makefile.am +++ b/src/Main/Makefile.am @@ -10,6 +10,14 @@ else MPLAYER_LIBS = endif +if ENABLE_MSERVER_AS +MSERVER_LIBS = $(top_builddir)/src/Server/libServer.a +MSERVER_BINS = fgmp +else +MSERVER_LIBS = +MSERVER_BINS = +endif + if ENABLE_NETWORK_OLK NETWORK_LIBS = $(top_builddir)/src/NetworkOLK/libNetworkOLK.a else @@ -40,7 +48,7 @@ AM_CXXFLAGS = -DPKGLIBDIR=\"$(pkglibdir)\" EXTRA_DIST = 3dfx.sh runfgfs.in runfgfs.bat.in -bin_PROGRAMS = fgfs +bin_PROGRAMS = fgfs $(MSERVER_BINS) noinst_SCRIPTS = runfgfs.bat runfgfs @@ -110,4 +118,12 @@ fgfs_LDADD = \ $(opengl_LIBS) \ $(audio_LIBS) +if ENABLE_MSERVER_AS + +fgmp_SOURCES = bootstrap.cxx + +fgmp_LDADD = $(fgfs_LDADD) $(MSERVER_LIBS) + +endif + INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/Makefile.am b/src/Makefile.am index d88af9347..10470774c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,6 +16,12 @@ else MPLAYER_DIRS = endif +if ENABLE_MSERVER_AS +MSERVER_DIRS = Server +else +MSERVER_DIRS = +endif + if ENABLE_NETWORK_OLK NETWORK_DIRS = NetworkOLK else @@ -38,6 +44,7 @@ SUBDIRS = \ Navaids \ Network \ $(MPLAYER_DIRS) \ + $(MSERVER_DIRS) \ $(NETWORK_DIRS) \ Objects \ Replay \ diff --git a/src/Server/Makefile.am b/src/Server/Makefile.am new file mode 100644 index 000000000..4b55b0d0b --- /dev/null +++ b/src/Server/Makefile.am @@ -0,0 +1,36 @@ +noinst_LIBRARIES = libServer.a +noinst_PROGRAMS = buftest msgtest + +if ENABLE_MSERVER_AS + +MSERVER_AS = \ + msg_0001_hello.cxx \ + msg_0001_hello.hxx \ + messagebuf.cxx \ + messagebuf.hxx \ + message.cxx \ + message.hxx + +MSERVER_BUF = buftest.cxx + +MSERVER_MSG = msgtest.cxx + +else + +MSERVER_AS = + +MSERVER_BUF = + +MSERVER_MSG = + +endif + +libServer_a_SOURCES = $(MSERVER_AS) + +buftest_SOURCES = $(MSERVER_BUF) +buftest_LDADD = libServer.a + +msgtest_SOURCES = $(MSERVER_MSG) +msgtest_LDADD = libServer.a + +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/Server/buftest.cxx b/src/Server/buftest.cxx new file mode 100644 index 000000000..f7bbe0547 --- /dev/null +++ b/src/Server/buftest.cxx @@ -0,0 +1,74 @@ +#include "message.hxx" + +main(int argc, char **argv) +{ + FGMPSMessageBuf buf1, buf2; + + buf1.clr(); + buf1.put(fgmps_som8, true); + buf1.put(1); + for (int i=0; i<256; i++) { + buf1.put(fgmps_uchar, true); + buf1.put(i); + } + buf1.put(fgmps_eom, true); + + buf2.set(buf1.str()); + + bool done=false; + while (!done) { + unsigned char mid8, uval8; + unsigned int mid16, uval16; + unsigned long uval32; + unsigned long long uval64; + char val8; + int val16; + long val32; + long long val64; + float valf; + double vald; + string vals; + printf("dump: "); + for (int i=0; i<16; i++) printf("%02x ", buf2.peek(i)); + printf("\n"); + try { + int tag = buf2.get(true); + switch (tag) { + case fgmps_som8: + mid8 = *(unsigned char *)buf2.read1(); + printf("Start Message ID = %02x\n", mid8); + break; + case fgmps_som16: + mid16 = *(unsigned int *)buf2.read2(); + printf("Start Message ID = %04x\n", mid16); + break; + case fgmps_eom: + printf("End Of Message\n", tag); + done = true; + break; + case fgmps_uchar: + uval8 = *(unsigned char *)buf2.read1(); + printf("uchar = %02x\n", uval8); + break; + case fgmps_uint: + uval16 = *(unsigned int *)buf2.read2(); + printf("uint = %04x\n", uval16); + break; + case fgmps_ulong: + uval32 = *(unsigned long *)buf2.read4(); + printf("ulong = %08lx\n", uval32); + break; + case fgmps_ulonglong: + uval64 = *(unsigned long long *)buf2.read8(); + printf("ulonglong = %16llx\n", uval64); + break; + default: + printf("Unknown prefix = %02x\n", tag); + done = true; + break; + } + } catch (FGMPSDataException e) { + done = true; + } + } +} diff --git a/src/Server/message.cxx b/src/Server/message.cxx new file mode 100644 index 000000000..e06964c5e --- /dev/null +++ b/src/Server/message.cxx @@ -0,0 +1,34 @@ +// message.hxx -- Multiplayer Client/Server message base class +// +// Written by John Barrett, started November 2003. +// +// Copyright (C) 2003 John R. Barrett - jbarrett@accesshosting.com +// +// 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + + +#include "message.hxx" + +FGMPSMessage::FGMPSMessage() +{ + msgid = 0x0000; + elements[0].type = fgmps_null; + elements[0].data = NULL; + +} + + + diff --git a/src/Server/message.hxx b/src/Server/message.hxx new file mode 100644 index 000000000..35c7e5111 --- /dev/null +++ b/src/Server/message.hxx @@ -0,0 +1,83 @@ +// message.hxx -- Multiplayer Client/Server message base class +// +// Written by John Barrett, started November 2003. +// +// Copyright (C) 2003 John R. Barrett - jbarrett@accesshosting.com +// +// 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + + +#ifndef _FG_MPS_MESSAGE_HXX +#define _FG_MPS_MESSAGE_HXX + +#include + +#include STL_STRING +#include + +SG_USING_STD(string); +SG_USING_STD(invalid_argument); + +#include "messagebuf.hxx" + +typedef enum +{ + fgmps_null = 0x00, + fgmps_uchar = 0xf0, + fgmps_uint = 0xf1, + fgmps_ulong = 0xf2, + fgmps_ulonglong = 0xf3, + fgmps_char = 0xf4, + fgmps_int = 0xf5, + fgmps_long = 0xf6, + fgmps_longlong = 0xf7, + fgmps_float = 0xf8, + fgmps_double = 0xf9, + fgmps_string = 0xfa, + fgmps_reserved = 0xfb, + fgmps_eom = 0xfc, + fgmps_som8 = 0xfd, + fgmps_som16 = 0xfe, + fgmps_esc = 0xfe +} FGMPSMsgElementType; + +typedef struct +{ + FGMPSMsgElementType type; + void * data; +} FGMPSMsgElementEntry; + +#define FGMPSMsgElementArrayEnd {fgmps_null, 0} + +class FGMPSMessage +{ +private: + FGMPSMsgElementEntry elements[1]; + static unsigned int msgid; +protected: + FGMPSMessageBuf msg; +public: + FGMPSMessage(); + ~FGMPSMessage() {} + + virtual string encodemsg() {} + virtual FGMPSMessage* decodemsg(string msg) {} + virtual FGMPSMsgElementEntry* getelements() { return elements; } + virtual unsigned int getmessageid() { return msgid; } + +}; + +#endif diff --git a/src/Server/messagebuf.cxx b/src/Server/messagebuf.cxx new file mode 100644 index 000000000..f5ff9f218 --- /dev/null +++ b/src/Server/messagebuf.cxx @@ -0,0 +1,137 @@ +#include "messagebuf.hxx" + +#include + +unsigned char FGMPSMessageBuf::get(bool raw) +{ + if (pos >= buf.length()) + throw FGMPSDataException( "FGMPSMessageBuf: Read past end of buffer" ); + if (raw) return buf[pos++]; + if ((unsigned char)buf[pos] == 0xff) { + pos++; + return ((unsigned char)buf[pos++] ^ 0xff); + } + return buf[pos++]; +} + +void FGMPSMessageBuf::put(unsigned char byte, bool raw) +{ + if (!raw) { + if ((byte & 0xf0) == 0xf0) { + buf += 0xff; + byte = byte ^ 0xff; + } + } + buf += byte; +} + +void FGMPSMessageBuf::write1(void* data) +{ + put(*(unsigned char *)data); +} + +void FGMPSMessageBuf::write2(void* data) +{ + *((uint16_t*)tmp) = htons(*((uint16_t*)data)); + put(tmp[0]); + put(tmp[1]); +} + +void FGMPSMessageBuf::write4(void* data) +{ + *((uint32_t*)tmp) = htonl(*((uint32_t*)data)); + put(tmp[0]); + put(tmp[1]); + put(tmp[2]); + put(tmp[3]); +} + +void FGMPSMessageBuf::write8(void* data) +{ + *((uint32_t*)tmp+0) = htonl(*((uint32_t*)data+4)); + *((uint32_t*)tmp+4) = htonl(*((uint32_t*)data+0)); + put(tmp[0]); + put(tmp[1]); + put(tmp[2]); + put(tmp[3]); + put(tmp[4]); + put(tmp[5]); + put(tmp[6]); + put(tmp[7]); +} + +void FGMPSMessageBuf::writef(float data) +{ + write4(&data); +} + +void FGMPSMessageBuf::writed(double data) +{ + write8(&data); +} + +void FGMPSMessageBuf::writes(string data) +{ + for (int i=0; i + +#include STL_STRING +#include + +SG_USING_STD(string); +SG_USING_STD(invalid_argument); + +class FGMPSDataException : public invalid_argument +{ +public: + FGMPSDataException( const string& what_string ) + : invalid_argument(what_string) {} +}; + +class FGMPSMessageBuf +{ + +private: + string buf; + size_t pos; + unsigned char tmp[16]; + +public: + + FGMPSMessageBuf() { init(""); } + FGMPSMessageBuf(string data) { init(data); } + + ~FGMPSMessageBuf() {} + + void init(string data) + { + buf = data; + pos = 0; + } + + void clr() { buf = ""; } + void add(string data) { buf += data; } + void set(string data) { buf = data; } + string& str() { return buf; } + size_t ofs() { return pos; } + void ofs(size_t val) { pos = val; } + + unsigned char get(bool raw = false); + unsigned char peek(size_t ofs = 0) { return buf[pos+ofs]; } + void put(unsigned char byte, bool raw = false); + + void write1(void* data); + void write2(void* data); + void write4(void* data); + void write8(void* data); + void writef(float data); + void writed(double data); + void writes(string data); + + void* read1(); + void* read2(); + void* read4(); + void* read8(); + float readf(); + double readd(); + string reads(size_t length); + + string& buffer() { return buf; } +}; + +#endif diff --git a/src/Server/msg_0001_hello.cxx b/src/Server/msg_0001_hello.cxx new file mode 100644 index 000000000..a0fad4ea9 --- /dev/null +++ b/src/Server/msg_0001_hello.cxx @@ -0,0 +1,37 @@ +// message.hxx -- Multiplayer Client/Server message base class +// +// Written by John Barrett, started November 2003. +// +// Copyright (C) 2003 John R. Barrett - jbarrett@accesshosting.com +// +// 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + + +#include "msg_0001_hello.hxx" + +FGMPSMsg0001Hello::FGMPSMsg0001Hello() +{ + msgid = 0x0001; + elements[0].type = fgmps_uint; elements[0].data = &this->vermajor; + elements[1].type = fgmps_uint; elements[0].data = &this->verminor; + elements[2].type = fgmps_uint; elements[0].data = &this->verpatch; + elements[3].type = fgmps_string; elements[0].data = &this->servname; + elements[4].type = fgmps_null; elements[4].data = NULL; +} + + + + diff --git a/src/Server/msg_0001_hello.hxx b/src/Server/msg_0001_hello.hxx new file mode 100644 index 000000000..9da5bd323 --- /dev/null +++ b/src/Server/msg_0001_hello.hxx @@ -0,0 +1,48 @@ +// message.hxx -- Multiplayer Client/Server message base class +// +// Written by John Barrett, started November 2003. +// +// Copyright (C) 2003 John R. Barrett - jbarrett@accesshosting.com +// +// 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + + +#ifndef _FG_MPS_MSG0001_HXX +#define _FG_MPS_MSG0001_HXX + +#include "message.hxx" + +class FGMPSMsg0001Hello +{ +private: + FGMPSMsgElementEntry elements[5]; + unsigned int msgid; +public: + FGMPSMsg0001Hello(); + ~FGMPSMsg0001Hello() {} + + virtual string encodemsg() {} + virtual FGMPSMessage* decodemsg(string msg) {} + virtual FGMPSMsgElementEntry* getelements() { return elements; } + virtual unsigned int getmessageid() { return msgid; } + + unsigned int vermajor; + unsigned int verminor; + unsigned int verpatch; + string servname; +}; + +#endif diff --git a/src/Server/msgtest.cxx b/src/Server/msgtest.cxx new file mode 100644 index 000000000..96248a6fe --- /dev/null +++ b/src/Server/msgtest.cxx @@ -0,0 +1,6 @@ +#include "messagebuf.hxx" + +main(int argc, char **argv) +{ + printf("Hello\n"); +}