Initial commit.

This commit is contained in:
Ronald Kinard 2015-02-22 23:36:26 -06:00
commit a3eeb02f32
22 changed files with 5754 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
/client
/server
/server.log
/*.o

140
Makefile Normal file
View file

@ -0,0 +1,140 @@
# Copyright (C) 2000 by DooM Legacy Team.
#
# 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.
#
# DESCRIPTION:
# Makefile for DooM Legacy Master Server
# Created on 06/23/2000 by Thierry Van Elsuwe
# e-mail: hurdler@newdoom.com
#
#-----------------------------------------------------------------------------
PORT=28900
#PORT=7896
#*******************************************************************#
CCFILES=common.cpp ipcs.cpp crypt.cpp md5.cpp
Main_CCFILES=server.cpp #client.cpp
#******************************************************************#
MYSQL_CONFIG?= mysql_config
MYSQL_CFLAGS?=$(shell $(MYSQL_CONFIG) --cflags)
MYSQL_LIBS?=$(shell $(MYSQL_CONFIG) --libs)
CXXFLAGS+=-Wall -O3 -Wextra
ifdef MINGW
LIBS+=-lws2_32
else
LIBS+=-lm
endif
CXXFLAGS+=$(MYSQL_CFLAGS)
LIBS+=$(MYSQL_LIBS)
ifdef DEBUG
CXXFLAGS+=-g -D__DEBUG__
endif
SRCS=$(CCFILES) $(Main_CCFILES)
OFILES=$(CCFILES:.cpp=.o)
Main_OFILES=$(Main_CCFILES:.cpp=.o)
EXEFILE=$(Main_CCFILES:.cpp=)
#####################################################################
.SUFFIXES: .cpp .h
default: init $(EXEFILE) end
init:
@echo
@echo "Compiling options:"
@echo " CXX : $(CXX)"
@echo " LDFLAGS : $(LDFLAGS)"
@echo " LIBS : $(LIBS)"
@echo " CXXFLAGS: $(CXXFLAGS)"
@echo
@echo "Files:"
@echo " SRCS : $(SRCS)"
@echo " OFILES : $(OFILES) $(Main_OFILES)"
@echo " EXEFILE : $(EXEFILE)"
@echo
end:
@echo
@echo "*** Makefile ended successfully ***"
@echo
#####################################################################
$(EXEFILE): $(OFILES) $(Main_OFILES)
@echo Linking ...
@$(CXX) $(LDFLAGS) $(OFILES) $@.o -o $@ $(LIBS)
ifndef CYGWIN
ifndef MINGW
@chmod 755 $@
endif
endif
@echo File $@ has been created
#####################################################################
.cpp.o:
@echo Compiling $< -\> $@
@$(CXX) $(CXXFLAGS) $(INCS) -c $< -o $@
#####################################################################
debug: debug_
debug_:
@make "CXXFLAGS = $(CXXFLAGS) -D__DEBUG__"
@echo
clean: clean_
clean_:
@echo
@echo Removing obejcts files, executable files and eventually core file...
@rm -f $(OFILES) $(Main_OFILES) $(EXEFILE) core
@echo
realclean: clean
@echo Removing backup files...
@rm -f *~ *.bak
@echo
depend: dep
dep:
@echo
@echo Make dependencies...
@makedepend -- $(CXXFLAGS) -- $(Main_CCFILES) $(CCFILES) 2> /dev/null
@rm -f Makefile.bak
@echo
BAKFILE = ../SRB2MasterServer
backup: bak
bak: clean
@echo Copy files to $(BAKFILE).tgz...
@tar cvf $(BAKFILE).tar * > /dev/null
@gzip $(BAKFILE).tar
@mv $(BAKFILE).tar.gz $(BAKFILE).tgz
@echo Removing backup files...
@rm -f *~ *.bak
@echo
#mrproper: dep clean default
mrproper: clean default
install: mrproper
@echo "Launching the server, port $(PORT)..."
@./server $(PORT)
@echo

230
Master.dsp Normal file
View file

@ -0,0 +1,230 @@
# Microsoft Developer Studio Project File - Name="MasterServer" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=MasterServer - Win32 Client Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Master.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Master.mak" CFG="MasterServer - Win32 Client Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "MasterServer - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "MasterServer - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "MasterServer - Win32 Client Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "MasterServer - Win32 Client Release" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "MasterServer - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../bin/VC/Release/MasterServer"
# PROP Intermediate_Dir "../../objs/VC/Release/MasterServer"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "_POSIX_" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib wsock32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/VC/Release/MasterServer.exe"
!ELSEIF "$(CFG)" == "MasterServer - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../../bin/VC/Debug/MasterServer"
# PROP Intermediate_Dir "../../objs/VC/Debug/MasterServer"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "_WIN32" /D "__DEBUG__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "_POSIX_" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/VC/Debug/MasterServer.exe" /pdbtype:sept
!ELSEIF "$(CFG)" == "MasterServer - Win32 Client Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "MasterServer___Win32_Client_Debug"
# PROP BASE Intermediate_Dir "MasterServer___Win32_Client_Debug"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../../bin/VC/Debug/MasterClient"
# PROP Intermediate_Dir "../../objs/VC/Debug/MasterClient"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "__STDC__" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "_WIN32" /D "__DEBUG__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "_POSIX_" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/VC/Debug/MasterServer.exe" /pdbtype:sept
# ADD LINK32 kernel32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/VC/Debug/MasterClient.exe" /pdbtype:sept
!ELSEIF "$(CFG)" == "MasterServer - Win32 Client Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "MasterServer___Win32_Client_Release"
# PROP BASE Intermediate_Dir "MasterServer___Win32_Client_Release"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../bin/VC/Release/MasterClient"
# PROP Intermediate_Dir "../../objs/VC/Release/MasterClient"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "_POSIX_" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib wsock32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/VC/Release/MasterServer.exe"
# ADD LINK32 kernel32.lib wsock32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/VC/Release/MasterClient.exe"
!ENDIF
# Begin Target
# Name "MasterServer - Win32 Release"
# Name "MasterServer - Win32 Debug"
# Name "MasterServer - Win32 Client Debug"
# Name "MasterServer - Win32 Client Release"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\client.cpp
!IF "$(CFG)" == "MasterServer - Win32 Release"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "MasterServer - Win32 Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "MasterServer - Win32 Client Debug"
# PROP BASE Exclude_From_Build 1
!ELSEIF "$(CFG)" == "MasterServer - Win32 Client Release"
# PROP BASE Exclude_From_Build 1
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\common.cpp
# End Source File
# Begin Source File
SOURCE=.\crypt.cpp
# End Source File
# Begin Source File
SOURCE=.\ipcs.cpp
# End Source File
# Begin Source File
SOURCE=.\server.cpp
!IF "$(CFG)" == "MasterServer - Win32 Release"
!ELSEIF "$(CFG)" == "MasterServer - Win32 Debug"
!ELSEIF "$(CFG)" == "MasterServer - Win32 Client Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "MasterServer - Win32 Client Release"
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\srvlist.cpp
# End Source File
# Begin Source File
SOURCE=.\stats.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\common.h
# End Source File
# Begin Source File
SOURCE=.\ipcs.h
# End Source File
# Begin Source File
SOURCE=.\srvlist.h
# End Source File
# Begin Source File
SOURCE=.\stats.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

38
Master.sln Normal file
View file

@ -0,0 +1,38 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MasterServer", "Master.vcproj", "{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Client Debug|Win32 = Client Debug|Win32
Client Debug|x64 = Client Debug|x64
Client Release|Win32 = Client Release|Win32
Client Release|x64 = Client Release|x64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Client Debug|Win32.ActiveCfg = Client Debug|Win32
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Client Debug|Win32.Build.0 = Client Debug|Win32
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Client Debug|x64.ActiveCfg = Client Debug|x64
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Client Debug|x64.Build.0 = Client Debug|x64
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Client Release|Win32.ActiveCfg = Client Release|Win32
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Client Release|Win32.Build.0 = Client Release|Win32
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Client Release|x64.ActiveCfg = Client Release|x64
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Client Release|x64.Build.0 = Client Release|x64
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Debug|Win32.ActiveCfg = Debug|Win32
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Debug|Win32.Build.0 = Debug|Win32
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Debug|x64.ActiveCfg = Debug|x64
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Debug|x64.Build.0 = Debug|x64
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Release|Win32.ActiveCfg = Release|Win32
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Release|Win32.Build.0 = Release|Win32
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Release|x64.ActiveCfg = Release|x64
{6AEBAD84-BCB1-4302-A453-7AAD1DF006DA}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

1063
Master.vcproj Normal file

File diff suppressed because it is too large Load diff

159
MasterClient.dev Normal file
View file

@ -0,0 +1,159 @@
[Project]
FileName=MasterClient.dev
Name=MasterClient
UnitCount=7
Type=1
Ver=1
ObjFiles=
Includes=
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-Wall_@@_
CppCompiler=-Wall_@@_
Linker=-lwsock32_@@_
IsCpp=1
Icon=
ExeOutput=..\..\bin
ObjectOutput=..\..\objs\MasterClient
OverrideOutput=0
OverrideOutputName=MasterServer.exe
HostApplication=
Folders=Client,Common
CommandLine=
UseCustomMakefile=0
CustomMakefile=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000010001001001010
[Unit1]
FileName=common.cpp
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=1
OverrideBuildCmd=0
BuildCmd=
[Unit2]
FileName=ipcs.cpp
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=2
OverrideBuildCmd=0
BuildCmd=
[Unit7]
FileName=Makefile
CompileCpp=1
Folder=
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit8]
FileName=stats.h
Folder=Server
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
CompileCpp=1
[Unit9]
FileName=common.h
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit11]
FileName=Makefile
CompileCpp=1
Folder=
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit12]
FileName=srvlist.h
CompileCpp=1
Folder=Server
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit3]
FileName=crypt.cpp
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=4
OverrideBuildCmd=0
BuildCmd=
[Unit4]
FileName=client.cpp
CompileCpp=1
Folder=Client
Compile=1
Link=1
Priority=7
OverrideBuildCmd=0
BuildCmd=$(CPP) -c client.cpp -o ../../../objs/MasterServer/client.o $(CXXFLAGS)
[Unit5]
FileName=common.h
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit6]
FileName=ipcs.h
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

169
MasterServer.dev Normal file
View file

@ -0,0 +1,169 @@
[Project]
FileName=MasterServer.dev
Name=MasterServer
UnitCount=11
Type=1
Ver=1
ObjFiles=
Includes=
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-Wall_@@_-DDEBUG_@@_
CppCompiler=-Wall_@@_-DDEBUG_@@_
Linker=-lwsock32_@@_-lmysql_@@_
IsCpp=1
Icon=
ExeOutput=..\..\bin
ObjectOutput=..\..\objs\MasterServer
OverrideOutput=0
OverrideOutputName=MasterServer.exe
HostApplication=
Folders=Common,Server
CommandLine=28900
UseCustomMakefile=0
CustomMakefile=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000011001001001010
[Unit1]
FileName=common.cpp
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=1
OverrideBuildCmd=0
BuildCmd=
[Unit2]
FileName=ipcs.cpp
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=2
OverrideBuildCmd=0
BuildCmd=
[Unit3]
FileName=srvlist.cpp
CompileCpp=1
Folder=Server
Compile=1
Link=1
Priority=3
OverrideBuildCmd=0
BuildCmd=
[Unit4]
FileName=crypt.cpp
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=4
OverrideBuildCmd=0
BuildCmd=
[Unit5]
FileName=stats.cpp
CompileCpp=1
Folder=Server
Compile=1
Link=1
Priority=5
OverrideBuildCmd=0
BuildCmd=
[Unit6]
FileName=server.cpp
CompileCpp=1
Folder=Server
Compile=1
Link=1
Priority=6
OverrideBuildCmd=0
BuildCmd=
[Unit8]
FileName=common.h
Folder=Common
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
CompileCpp=1
[Unit9]
FileName=ipcs.h
CompileCpp=1
Folder=Common
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit10]
FileName=Makefile
CompileCpp=1
Folder=
Compile=0
Link=0
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit11]
FileName=srvlist.h
CompileCpp=1
Folder=Server
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit7]
FileName=stats.h
CompileCpp=1
Folder=Server
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit13]
FileName=LIVE_MySQL.h
CompileCpp=1
Folder=Server
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

9
README.md Normal file
View file

@ -0,0 +1,9 @@
# SRB2 Master Server
This has been separated from the core SRB2 repo for cleanliness. It needs to be updated with documentation!
# License
Copyright (C) Sonic Team Junior, 2015
This code is made available under the terms of the GNU General Public License, version 2. You can see that license [here](http://www.gnu.org/licenses/gpl-2.0.html).

133
client.cpp Normal file
View file

@ -0,0 +1,133 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#include <time.h>
#include <string.h>
#include "ipcs.h"
#include "common.h"
//=============================================================================
static CClientSocket client_socket;
//static msg_t msg;
FILE *logfile;
//=============================================================================
static msg_t *getData(int argc, char *argv[])
{
static msg_t msg;
msg_server_t *info = (msg_server_t *)msg.buffer;
#if defined (_WIN32)
strcpy(info->header.buffer, "");
#else
strcpy(info->header.buffer, getpass("Enter password: "));
#endif
// default values if one of the param is not entered
strcpy(info->ip, "88.86.106.169");
strcpy(info->port, "5029");
strcpy(info->name, "Cueball's Dedicated Server");
strcpy(info->version, "1.09.4");
msg.type = ADD_PSERVER_MSG;
msg.length = sizeof (msg_server_t);
for (int i = 0; i < argc; i++)
{
// first: extra parameters (must be after all -param)
if (!strcasecmp(argv[i], "get"))
{
msg.type = GET_SERVER_MSG;
msg.length = 0;
}
else if (!strcasecmp(argv[i], "log"))
{
msg.type = GET_LOGFILE_MSG;
msg.length = sizeof (msg_server_t);
}
else if (!strcasecmp(argv[i], "erase"))
{
msg.type = ERASE_LOGFILE_MSG;
msg.length = sizeof (msg_server_t);
}
else if (!strcasecmp(argv[i], "remove"))
{
msg.type = REMOVE_PSERVER_MSG;
msg.length = sizeof (msg_server_t);
}
if (i >= argc-1)
continue;
// second: parameter requiring extra parameters
if (strcasecmp(argv[i], "-ip") == 0)
strcpy(info->ip, argv[i+1]);
else if (strcasecmp(argv[i], "-port") == 0)
strcpy(info->port, argv[i+1]);
else if (strcasecmp(argv[i], "-hostname") == 0)
strcpy(info->name, argv[i+1]);
else if (strcasecmp(argv[i], "-version") == 0)
strcpy(info->version, argv[i+1]);
else if (strcasecmp(argv[i], "-pass") == 0)
strcpy(info->header.buffer, argv[i+1]);
}
return &msg;
}
int main(int argc, char *argv[])
{
if (argc == 2)
{
printf("encrypt: %s\n", pCrypt(argv[1], "04"));
return 0;
}
else if (argc > 2)
{
if (client_socket.connect(argv[1], argv[2]) < 0)
{
conPrintf(RED, "Connect failed.\n");
return -1;
}
msg_t *msg = getData(argc, argv);
if (client_socket.write(msg) < 0)
{
dbgPrintf(RED, "Write failed.\n");
return -1;
}
switch (ntohl(msg->type))
{
case GET_SERVER_MSG:
case GET_LOGFILE_MSG:
while (client_socket.read(msg) >= 0)
{
if (ntohl(msg->length) == 0)
break;
printf("%s", msg->buffer);
}
break;
case REMOVE_PSERVER_MSG:
default:
break;
}
}
return 0;
}

207
common.cpp Normal file
View file

@ -0,0 +1,207 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
#include "common.h"
// ================================== GLOBALS =================================
static const char *fatal_error_msg[NUM_FATAL_ERROR] =
{
"Error: signal()",
"Error: select()",
"Error: read()",
"Error: write()",
};
// used by xxxPrintf() functions as temporary variable
static char str[1024] ="";
static va_list arglist;
#ifdef _WIN32
static size_t len = 0;
static HANDLE co = INVALID_HANDLE_VALUE;
static DWORD bytesWritten = 0;
static CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
#endif
// ================================= FUNCTIONS ================================
/*
* clearScreen():
*/
void clearScreen()
{
#ifdef _WIN32
#else
printf("\033[0m \033[2J \033[0;0H");
#endif
}
/*
* fatalError():
*/
void fatalError(fatal_error_t num)
{
clearScreen();
printf("\n");
perror(fatal_error_msg[num]);
printf("\n");
exit(-1);
}
/*
* dbgPrintf():
*/
#ifdef _WIN32
void dbgPrintf(DWORDLONG col, const char *lpFmt, ...)
#else
void dbgPrintf(const char *col, const char *lpFmt, ...)
#endif
{
#if defined (__DEBUG__)
va_start(arglist, lpFmt);
vsnprintf(str, sizeof str, lpFmt, arglist);
va_end(arglist);
#ifdef _WIN32
len = strlen(str);
co = GetStdHandle(STD_OUTPUT_HANDLE);
if (co == INVALID_HANDLE_VALUE)
return;
if (col == DEFCOL)
{
if (!GetConsoleScreenBufferInfo(co, &ConsoleScreenBufferInfo))
ConsoleScreenBufferInfo.wAttributes =
FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE;
SetConsoleTextAttribute(co, (WORD)col);
}
if (GetFileType(co) == FILE_TYPE_CHAR)
WriteConsoleA(co, str, (DWORD)len, &bytesWritten, NULL);
else
WriteFile(co, str, (DWORD)len, &bytesWritten, NULL);
if (col != DEFCOL)
SetConsoleTextAttribute(co,
ConsoleScreenBufferInfo.wAttributes);
#else
printf("%s%s", col, str);
fflush(stdout);
#endif
#else
(void)col;
(void)lpFmt;
#endif
}
/*
* conPrintf()
*/
#ifdef _WIN32
void conPrintf(DWORDLONG col, const char *lpFmt, ...)
#else
void conPrintf(const char *col, const char *lpFmt, ...)
#endif
{
va_start(arglist, lpFmt);
vsnprintf(str, sizeof str, lpFmt, arglist);
va_end(arglist);
#ifdef _WIN32
len = strlen(str);
co = GetStdHandle(STD_OUTPUT_HANDLE);
if (col == DEFCOL)
{
if (!GetConsoleScreenBufferInfo(co, &ConsoleScreenBufferInfo))
ConsoleScreenBufferInfo.wAttributes =
FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE;
SetConsoleTextAttribute(co, (WORD)col);
}
if (co == INVALID_HANDLE_VALUE)
return;
if (GetFileType(co) == FILE_TYPE_CHAR)
WriteConsoleA(co, str, (DWORD)len, &bytesWritten, NULL);
else
WriteFile(co, str, (DWORD)len, &bytesWritten, NULL);
if (col != DEFCOL)
SetConsoleTextAttribute(co,
ConsoleScreenBufferInfo.wAttributes);
#else
printf("%s%s", col, str);
fflush(stdout);
#endif
}
/*
* logPrintf():
*/
void logPrintf(FILE *f, const char *lpFmt, ...)
{
char *ct;
time_t t;
va_start(arglist, lpFmt);
vsnprintf(str, sizeof str, lpFmt, arglist);
va_end(arglist);
t = time(NULL);
ct = ctime(&t);
ct[strlen(ct)-1] = '\0';
fprintf(f, "%s: %s", ct, str);
fflush(f);
#if defined (__DEBUG__)
#ifdef _WIN32
len = strlen(str);
printf("%s", str);
#else
printf("%s%s", DEFCOL, str);
#endif
fflush(stdout);
#endif
}
/*
* openFile():
*/
FILE *openFile(const char *filename)
{
return fopen(filename, "a+t");
}
void strrand(char *s, const int len) {
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[len] = 0;
}

151
common.h Normal file
View file

@ -0,0 +1,151 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#ifndef _COMMON_H_
#define _COMMON_H_
#ifdef __GNUC__
#include <unistd.h>
#include <stdint.h>
#define UINT8 uint8_t
#define SINT8 int8_t
#define UINT16 uint16_t
#define INT16 int16_t
#define INT32 int32_t
#define UINT32 uint32_t
#define INT64 int64_t
#define UINT64 uint64_t
#define ATTRPACK __attribute__ ((packed))
#elif defined ( _MSC_VER)
#include <wtypes.h>
#define UINT8 unsigned __int8
#define SINT8 signed __int8
#define UINT16 unsigned __int16
#define INT16 __int16
#define INT32 __int32
#define UINT32 unsigned __int32
#define INT64 __int64
#define UINT64 unsigned __int64
typedef long ssize_t;
#endif
#ifndef ATTRPACK
#define ATTRPACK
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#if defined (_WIN32) || defined (__OS2__)
#ifdef __GNUC__
#define strcasecmp stricmp
#elif defined (_MSC_VER)
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strcasecmp _stricmp
#pragma warning(disable : 4244)
#endif
#endif
// ================================ DEFINITIONS ===============================
#ifdef _WIN32
#ifdef __GNUC__
#include <windef.h>
#include <stdarg.h>
#include <winbase.h>
#include <wincon.h>
#endif
#define DEFCOL 0xD0E0F0C0 // codes couleurs ANSI
#define BLACK 0
#define RED FOREGROUND_RED
#define GREEN FOREGROUND_GREEN
#define BROWN FOREGROUND_GREEN|FOREGROUND_RED
#define BLUE FOREGROUND_BLUE
#define PURPLE FOREGROUND_RED|FOREGROUND_BLUE
#define CYAN FOREGROUND_BLUE|FOREGROUND_GREEN
#define LIGHTGRAY FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED
#define DARKGRAY FOREGROUND_INTENSITY
#define LIGHTRED FOREGROUND_RED|FOREGROUND_INTENSITY
#define LIGHTGREEN FOREGROUND_GREEN|FOREGROUND_INTENSITY
#define YELLOW FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY
#define LIGHTBLUE FOREGROUND_BLUE|FOREGROUND_INTENSITY
#define MAGENTA FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY
#define LIGHTCYAN FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY
#define WHITE FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY
#else
#define DEFCOL "\033[0m" // codes couleurs ANSI
#define BLACK "\033[0;30m"
#define RED "\033[0;31m"
#define GREEN "\033[0;32m"
#define BROWN "\033[0;33m"
#define BLUE "\033[0;34m"
#define PURPLE "\033[0;35m"
#define CYAN "\033[0;36m"
#define LIGHTGRAY "\033[0;37m"
#define DARKGRAY "\033[1;30m"
#define LIGHTRED "\033[1;31m"
#define LIGHTGREEN "\033[1;32m"
#define YELLOW "\033[1;33m"
#define LIGHTBLUE "\033[1;34m"
#define MAGENTA "\033[1;35m"
#define LIGHTCYAN "\033[1;36m"
#define WHITE "\033[1;37m"
#endif
typedef enum
{
FE_SIGNAL_ERR,
FE_SELECT_ERR,
FE_READ_ERR,
FE_WRITE_ERR,
NUM_FATAL_ERROR
} fatal_error_t;
// ================================== PROTOS ==================================
void clearScreen();
void fatalError(fatal_error_t);
void logPrintf(FILE *, const char *, ...);
#ifdef _WIN32
void dbgPrintf(DWORDLONG col, const char *lpFmt, ...);
void conPrintf(DWORDLONG col, const char *lpFmt, ...);
#else
void dbgPrintf(const char *col, const char *lpFmt, ...);
void conPrintf(const char *col, const char *lpFmt, ...);
#endif
FILE *openFile(const char *filename);
const char *pCrypt(const char *pw, const char *salt);
// ================================== STRINGS =================================
void strrand(char *s, const int len);
// ================================== EXTERNS =================================
#endif

278
crypt.cpp Normal file
View file

@ -0,0 +1,278 @@
#include "common.h"
static SINT8 IP[] =
{
58,50,42,34,26,18,10, 2,
60,52,44,36,28,20,12, 4,
62,54,46,38,30,22,14, 6,
64,56,48,40,32,24,16, 8,
57,49,41,33,25,17, 9, 1,
59,51,43,35,27,19,11, 3,
61,53,45,37,29,21,13, 5,
63,55,47,39,31,23,15, 7,
};
static SINT8 FP[] =
{
40, 8,48,16,56,24,64,32,
39, 7,47,15,55,23,63,31,
38, 6,46,14,54,22,62,30,
37, 5,45,13,53,21,61,29,
36, 4,44,12,52,20,60,28,
35, 3,43,11,51,19,59,27,
34, 2,42,10,50,18,58,26,
33, 1,41, 9,49,17,57,25,
};
static SINT8 PC1_C[] =
{
57,49,41,33,25,17, 9,
1,58,50,42,34,26,18,
10, 2,59,51,43,35,27,
19,11, 3,60,52,44,36,
};
static SINT8 PC1_D[] =
{
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14, 6,61,53,45,37,29,
21,13, 5,28,20,12, 4,
};
static SINT8 shifts[] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
static SINT8 PC2_C[] =
{
14,17,11,24, 1, 5,
3,28,15, 6,21,10,
23,19,12, 4,26, 8,
16, 7,27,20,13, 2,
};
static SINT8 PC2_D[] =
{
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32,
};
static SINT8 C[28];
static SINT8 D[28];
static SINT8 KS[16][48];
static SINT8 E[48];
static SINT8 e2[] =
{
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32, 1,
};
static SINT8 S[8][64] =
{
{
14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
},
{
15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
},
{
10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
},
{
7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
},
{
2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
},
{
12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
},
{
4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
},
{
13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
}
};
static SINT8 P[] =
{
16, 7,20,21,
29,12,28,17,
1,15,23,26,
5,18,31,10,
2, 8,24,14,
32,27, 3, 9,
19,13,30, 6,
22,11, 4,25,
};
static SINT8 L[64], *R = L + 32;
static SINT8 tempL[32];
static SINT8 f[32];
static SINT8 preS[48];
//=======================================================================
static void setKey(const SINT8 *key)
{
register INT32 i, j, k;
INT32 t;
for (i = 0; i < 28; i++)
{
C[i] = key[PC1_C[i]-1];
D[i] = key[PC1_D[i]-1];
}
for (i = 0; i < 16; i++)
{
for (k = 0; k < shifts[i]; k++)
{
t = C[0];
for (j = 0; j < 28-1; j++)
C[j] = C[j+1];
C[27] = t;
t = D[0];
for (j = 0; j < 28-1; j++)
D[j] = D[j+1];
D[27] = t;
}
for (j = 0; j < 24; j++)
{
KS[i][j] = C[PC2_C[j]-1];
KS[i][j+24] = D[PC2_D[j]-28-1];
}
}
for (i = 0; i < 48; i++)
E[i] = e2[i];
}
void enCrypt(SINT8 *block)
{
INT32 i, ii;
register INT32 t, j, k;
for (j = 0; j < 64; j++)
L[j] = block[IP[j]-1];
for (ii = 0; ii < 16; ii++)
{
i = ii;
for (j = 0; j < 32; j++)
tempL[j] = R[j];
for (j = 0; j < 48; j++)
preS[j] = R[E[j]-1] ^ KS[i][j];
for (j = 0; j < 8; j++)
{
t = 6*j;
k = S[j][(preS[t+0]<<5)+
(preS[t+1]<<3)+
(preS[t+2]<<2)+
(preS[t+3]<<1)+
(preS[t+4]<<0)+
(preS[t+5]<<4)];
t = 4*j;
f[t+0] = (k>>3)&01;
f[t+1] = (k>>2)&01;
f[t+2] = (k>>1)&01;
f[t+3] = (k>>0)&01;
}
for (j = 0; j < 32; j++)
R[j] = L[j] ^ f[P[j]-1];
for (j = 0; j < 32; j++)
L[j] = tempL[j];
}
for (j = 0; j < 32; j++)
{
t = L[j];
L[j] = R[j];
R[j] = t;
}
for (j = 0; j < 64; j++)
block[j] = L[FP[j]-1];
}
const char *pCrypt(const char *pw, const char *salt)
{
register INT32 i, j, c;
INT32 temp;
static SINT8 block[66];
static char iobuf[16];
for (i = 0; i < 66; i++)
block[i] = 0;
for (i = 0; (c = *pw) != '\0' && i < 64; pw++)
{
for (j = 0; j < 7; j++, i++)
block[i] = (c>>(6-j)) & 01;
i++;
}
setKey(block);
for (i = 0; i < 66; i++)
block[i] = 0;
for (i = 0; i < 2; i++)
{
c = *salt++;
iobuf[i] = c;
if (c > 'Z')
c -= 6;
if (c > '9')
c -= 7;
c -= '.';
for (j = 0; j < 6; j++)
{
if ((c>>j) & 01)
{
temp = E[6*i+j];
E[6*i+j] = E[6*i+j+24];
E[6*i+j+24] = temp;
}
}
}
for (i = 0; i < 25; i++)
enCrypt(block);
for (i = 0; i < 11; i++)
{
c = 0;
for (j = 0; j < 6; j++)
{
c <<= 1;
c |= block[6*i+j];
}
c += '.';
if (c > '9')
c += 7;
if (c > 'Z')
c += 6;
iobuf[i+2] = c;
}
iobuf[i+2] = 0;
if (iobuf[1] == 0)
iobuf[1] = iobuf[0];
return(iobuf);
}

595
ipcs.cpp Normal file
View file

@ -0,0 +1,595 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#ifdef __GNUC__
#include <unistd.h>
#endif
#ifdef _WIN32
//#include <winsock.h>
#else
#include <sys/types.h> // socket(),...
#include <sys/socket.h> // socket(),...
#endif
#include <stdlib.h> // atoi(),...
#include <signal.h> // signal(),...
#ifndef _WIN32
#include <netdb.h> // gethostbyname(),...
#endif
#ifdef _WIN32
#include <time.h>
#else
#include <sys/time.h> // timeval,... (TIMEOUT)
#endif
#include <string.h> // memset(),...
#include "ipcs.h"
#include "common.h"
typedef void Sigfunc(int);
#ifndef _WIN32
static void sigHandler(int signr);
static Sigfunc *mySignal(int signo, Sigfunc *func);
#endif
#ifdef _MSC_VER
#pragma warning(disable : 4127)
#endif
//=============================================================================
#if defined (_WIN32) || defined (__OS2__)
// it seems windows doesn't define that... maybe some other OS? OS/2
static int inet_aton(const char *hostname, struct in_addr *addr)
{
return ((addr->s_addr=inet_addr(hostname)) != INADDR_NONE);
}
#endif
/*
** CSocket()
*/
CSocket::CSocket()
{
dbgPrintf(DEFCOL, "Initializing socket... ");
#ifdef _WIN32
//#warning SIGPIPE needed
WSADATA winsockdata;
if (WSAStartup(MAKEWORD(1, 1), &winsockdata))
conPrintf(RED,"No TCP/IP driver detected");
#else
signal(SIGPIPE, sigHandler);
#endif
FD_ZERO(&rset);
memset(&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
dbgPrintf(DEFCOL, "DONE1.\n");
}
/*
** ~CSocket()
*/
CSocket::~CSocket()
{
dbgPrintf(DEFCOL, "Freeing socket... ");
#ifdef _WIN32
WSACleanup();
#endif
dbgPrintf(DEFCOL, "DONE2.\n");
}
/*
** getIP()
*/
int CSocket::getIP(const char *ip_addr)
{
struct hostent *host_ent;
dbgPrintf(DEFCOL, "get IP for %s... ", ip_addr);
if (!inet_aton(ip_addr, &addr.sin_addr))
{
host_ent = gethostbyname(ip_addr);
if (host_ent == NULL)
return GETHOSTBYNAME_ERROR;
memcpy(&addr.sin_addr, host_ent->h_addr_list[0],
sizeof (struct in_addr));
}
dbgPrintf(DEFCOL, "got %s. ", inet_ntoa(addr.sin_addr));
dbgPrintf(DEFCOL, "DONE3.\n");
return 0;
}
/*
** CClientSocket()
*/
CClientSocket::CClientSocket()
{
dbgPrintf(DEFCOL, "Initializing client socket... ");
socket_fd = (SOCKET)-1;
dbgPrintf(DEFCOL, "DONE4.\n");
}
/*
** ~CClientSocket()
*/
CClientSocket::~CClientSocket()
{
dbgPrintf(DEFCOL, "Freeing client socket... ");
if (socket_fd != (SOCKET)-1)
close(socket_fd);
dbgPrintf(DEFCOL, "DONE5.\n");
}
/*
** connect()
*/
int CClientSocket::connect(const char *ip_addr, const char *str_port)
{
dbgPrintf(DEFCOL, "Connect to %s %s...\n", ip_addr, str_port);
// put that in the constructor?
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == (SOCKET)-1)
return SOCKET_ERROR;
if (getIP(ip_addr) == GETHOSTBYNAME_ERROR)
return GETHOSTBYNAME_ERROR;
addr.sin_port = htons(atoi(str_port));
if (::connect(socket_fd, (struct sockaddr *) &addr, sizeof (addr)) < 0)
return CONNECT_ERROR;
FD_SET(socket_fd, &rset);
dbgPrintf(DEFCOL, "DONE6.\n");
return 0;
}
/*
* write()
*/
int CClientSocket::write(msg_t *msg)
{
int len;
if (msg->length < 0)
msg->length = (INT32)strlen(msg->buffer);
if (msg->length > PACKET_SIZE)
return WRITE_ERROR; // too big
len = msg->length + HEADER_SIZE;
msg->id = htonl(msg->id);
msg->type = htonl(msg->type);
msg->length = htonl(msg->length);
msg->room = htonl(msg->room);
dbgPrintf(DEFCOL, "Write a message %d (%s)... ", len, msg->buffer);
if (send(socket_fd, (const char *)msg, len, 0) != len)
return WRITE_ERROR;
dbgPrintf(DEFCOL, "DONE7.\n");
return 0;
}
/*
* read()
*/
int CClientSocket::read(msg_t *msg)
{
struct timeval timeout;
fd_set tset;
dbgPrintf(DEFCOL, "Waiting a message... ");
timeout.tv_sec = 60, timeout.tv_usec = 0;
memcpy(&tset, &rset, sizeof (tset));
if ((select(255, &tset, NULL, NULL, &timeout)) <= 0)
return TIMEOUT_ERROR;
if (!FD_ISSET(socket_fd, &tset))
return READ_ERROR;
dbgPrintf(DEFCOL, "Reading a message.\n");
if (recv(socket_fd, (char *)msg, HEADER_SIZE, 0) != HEADER_SIZE)
return READ_ERROR;
msg->id = ntohl(msg->id);
msg->type = ntohl(msg->type);
msg->length = ntohl(msg->length);
msg->room = ntohl(msg->room);
if (!msg->length) // work around a bug in Windows 2000
return 0;
if (msg->length > PACKET_SIZE)
return READ_ERROR; // packet too big
if (recv(socket_fd, msg->buffer, msg->length, 0) != msg->length)
return READ_ERROR;
dbgPrintf(DEFCOL, "DONE8.\n");
return 0;
}
/*
** CServerSocket()
*/
CServerSocket::CServerSocket()
{
size_t id;
dbgPrintf(DEFCOL, "Initializing server socket... ");
num_clients = 0;
accept_fd = udp_fd = (SOCKET)-1;
for (id = 0; id < MAX_CLIENT; id++)
client_fd[id] = (SOCKET)-1;
udp_addr.sin_family = AF_INET;
dbgPrintf(DEFCOL, "DONE9.\n");
}
/*
** ~CServerSocket()
*/
CServerSocket::~CServerSocket()
{
size_t id;
dbgPrintf(DEFCOL, "Freeing server socket... ");
if (udp_fd != (SOCKET)-1)
close(udp_fd);
if (accept_fd != (SOCKET)-1)
close(accept_fd);
for (id = 0; id < num_clients || id < MAX_CLIENT; id++)
if (client_fd[id] != (SOCKET)-1)
close(client_fd[id]);
dbgPrintf(DEFCOL, "DONE10.\n");
}
/*
** listen()
*/
int CServerSocket::listen(const char *str_port)
{
dbgPrintf(DEFCOL, "Listen on %s... ", str_port);
// Init TCP socket
if ((accept_fd = socket(AF_INET, SOCK_STREAM, 0)) == (SOCKET)-1)
return SOCKET_ERROR;
int one = 1; setsockopt(accept_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(int));
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(atoi(str_port));
if (bind(accept_fd, (struct sockaddr *) &addr, sizeof (addr)) < 0)
return BIND_ERROR;
if (::listen(accept_fd, 5) < 0)
return LISTEN_ERROR;
FD_SET(accept_fd, &rset);
// Init UDP socket
if ((udp_fd = socket(AF_INET, SOCK_DGRAM, 0)) == (SOCKET)-1)
return SOCKET_ERROR;
udp_addr.sin_addr.s_addr = htonl(INADDR_ANY);
udp_addr.sin_port = htons(atoi(str_port)+1);
if (bind(udp_fd, (struct sockaddr *) &udp_addr, sizeof (udp_addr)) < 0)
return BIND_ERROR;
FD_SET(udp_fd, &rset);
dbgPrintf(DEFCOL, "DONE11.\n");
return 0;
}
/*
* deleteClient():
*/
int CServerSocket::deleteClient(size_t id)
{
dbgPrintf(DEFCOL, "Deleting (client %u) of %u... ", id+1, num_clients);
FD_CLR(client_fd[id], &rset);
close(client_fd[id]);
if (num_clients != 0)
num_clients--;
client_fd[id] = client_fd[num_clients]; // move the top socket into this now empty space
memmove(&client_addr[id], &client_addr[num_clients], sizeof (client_addr[num_clients]));
client_fd[num_clients] = (SOCKET)-1; // now empty the top socket
memset(&client_addr[num_clients], 0 , sizeof (client_addr[num_clients]));
dbgPrintf(DEFCOL, "DONE12.\n");
return 0;
}
/*
* getUdpIP()
*/
const char *CServerSocket::getUdpIP(void)
{
return inet_ntoa(udp_in_addr.sin_addr);
}
/*
* getUdpPort()
*/
const char *CServerSocket::getUdpPort(bool offset)
{
static char buffer[8];
UINT16 port = htons(udp_in_addr.sin_port);
if (offset)
port--;
snprintf(buffer, sizeof buffer, "%d", port);
return buffer;
}
/*
* read(): wait message on a socket, if it's an accept, call the accept method,
* otherwise read the message and update msg->id to the right value
* (client cannot put valid entry in msg->id)
*/
int CServerSocket::read(msg_t *msg)
{
struct timeval timeout;
fd_set tset;
UINT32 id;
socklen_t lg = sizeof (addr);
timeout.tv_sec = 20, timeout.tv_usec = 0;
memcpy(&tset, &rset, sizeof (tset));
if ((select(255, &tset, NULL, NULL, &timeout)) <= 0)
{
msg->type = TIMEOUT_MSG;
return TIMEOUT_ERROR;
}
if (FD_ISSET(udp_fd, &tset))
{
msg->type = UDP_RECV_MSG; // This is a UDP packet
msg->length = recvfrom(udp_fd, msg->buffer, PACKET_SIZE, 0, (struct sockaddr *)&udp_in_addr, &lg);
return 0;
}
if (FD_ISSET(accept_fd, &tset))
{
msg->type = ACCEPT_MSG;
return this->accept();
}
id = 0;
while (!FD_ISSET(client_fd[id], &tset) && id < MAX_CLIENT)
id++;
// paranoia
if ( (id >= num_clients) || (id >= MAX_CLIENT) )
{
dbgPrintf(DEFCOL, "This should never happen\n");
return READ_ERROR;
}
dbgPrintf(DEFCOL, "Reading a message from (socket %u) for (client %u)... ", client_fd[id], id+1);
if (recv(client_fd[id], (char *)msg, HEADER_SIZE, 0) != HEADER_SIZE)
{
deleteClient(id); // the connection is not good with the client, kick him
return READ_ERROR;
}
//msg->id = ntohl(msg->id); // see comment above
msg->type = ntohl(msg->type);
msg->length = ntohl(msg->length);
msg->room = ntohl(msg->room);
if ((0 < msg->length) && (msg->length < PACKET_SIZE))
{
timeout.tv_sec = 0, timeout.tv_usec = 0; // the info should be already in the socket, so don't wait
memcpy(&tset, &rset, sizeof (tset));
if ((select(255, &tset, NULL, NULL, &timeout)) <= 0)
{
deleteClient(id);
return READ_ERROR;
}
if (!FD_ISSET(client_fd[id], &tset))
{
deleteClient(id);
return READ_ERROR;
}
if (recv(client_fd[id], msg->buffer, msg->length, 0) != msg->length)
{
deleteClient(id);
return READ_ERROR;
}
}
msg->id = id;
dbgPrintf(DEFCOL, "DONE13.\n");
return 0;
}
/*
* write():
*/
int CServerSocket::write(msg_t *msg)
{
struct timeval timeout;
fd_set tset;
int len;
dbgPrintf(DEFCOL, "Write a message... ");
FD_ZERO(&tset);
/*
* Be sure the msg->id is still valid; we cannot do
* a delete between a read and a write. Should we
* use a readpending set in read method, so we know
* that we are still waiting for writing? For now,
* it's the responsibility of server code.
*/
FD_SET(client_fd[msg->id], &tset);
timeout.tv_sec = 0, timeout.tv_usec = 0;
if ((select(255, NULL, &tset, NULL, &timeout)) <= 0)
{
deleteClient(msg->id); // this shouldn't happen if the net connection is good
return TIMEOUT_ERROR;
}
if (msg->length < 0)
msg->length = (INT32)strlen(msg->buffer);
if (msg->length > PACKET_SIZE)
return WRITE_ERROR; // too big
len = msg->length+HEADER_SIZE;
//msg->id = htonl(msg->id); // same comment as for read
msg->type = htonl(msg->type);
msg->length = htonl(msg->length);
if (send(client_fd[msg->id], (const char *)msg, len, 0) != len)
{
deleteClient(msg->id);
return WRITE_ERROR;
}
dbgPrintf(DEFCOL, "DONE14.\n");
return 0;
}
/*
* writeUDP()
*/
int CServerSocket::writeUDP(const char *data, size_t length, const char *ip, UINT16 port)
{
sockaddr_in sin;
struct timeval timeout;
fd_set tset;
FD_ZERO(&tset);
FD_SET(udp_fd, &tset);
if ((select(255, NULL, &tset, NULL, &timeout)) <= 0)
{
return TIMEOUT_ERROR;
}
sin.sin_family = AF_INET;
inet_aton(ip, &sin.sin_addr);
sin.sin_port = htons(port);
sendto(udp_fd, data, (int)length, 0, (sockaddr*)&sin, sizeof(sin));
return 0;
}
/*
* accept()
*/
int CServerSocket::accept()
{
socklen_t lg = sizeof (addr);
dbgPrintf(DEFCOL, "Accepting on (socket %u)... ", accept_fd);
if ((client_fd[num_clients] = ::accept(accept_fd, (struct sockaddr *) &addr, &lg)) == (SOCKET)-1)
{
//client_fd[num_clients] = (SOCKET)-1; // we haven't accepted the client, so set it at default value
return ACCEPT_ERROR;
}
if (num_clients < MAX_CLIENT-1)
{
extern FILE *sockfile;
logPrintf(sockfile, "Accepting on socket %u for client %u (%s:%i)\n",
client_fd[num_clients], num_clients+1, inet_ntoa(addr.sin_addr), htons(addr.sin_port));
memcpy(&client_addr[num_clients], &addr, sizeof (addr));
FD_SET(client_fd[num_clients], &rset);
num_clients++;
}
else // we have reached the maximum number of clients
{
// close the connection (meaning "try again" for the client)
close(client_fd[num_clients]);
client_fd[num_clients] = (SOCKET)-1;
return ACCEPT_ERROR;
}
//dbgPrintf(DEFCOL, "DONE15.\n");
return 0;
}
/*
* getClientIP()
*/
const char *CServerSocket::getClientIP(size_t id)
{
dbgPrintf(DEFCOL, "getClientIP: %u\n", id);
return inet_ntoa(client_addr[id].sin_addr);
}
/*
* getClientPort()
*/
const char *CServerSocket::getClientPort(size_t id)
{
static char buffer[8];
dbgPrintf(DEFCOL, "getClientPort: %u\n", id);
UINT16 port = htons(client_addr[id].sin_port);
snprintf(buffer, sizeof buffer, "%d", port);
return buffer;
}
/*
* mySignal()
*/
#ifndef _WIN32
static Sigfunc *mySignal(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
#if defined (SA_RESTART)
act.sa_flags = SA_RESTART;
#else
act.sa_flags = 0;
#endif
if (sigaction(signo, &act, &oact) < 0)
return SIG_ERR;
return oact.sa_handler;
}
/*
* sigHandler()
*/
static void sigHandler(int signr)
{
mySignal(signr, sigHandler);
switch (signr)
{
case SIGPIPE:
dbgPrintf(DEFCOL, "Catch SIG_PIPE\n");
/// TODO be sure the socket is closed if the client
/// didn't quit properly
break;
}
}
#endif

281
ipcs.h Normal file
View file

@ -0,0 +1,281 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#ifndef _IPCS_H_
#define _IPCS_H_
#include "common.h"
#if defined (_WIN32) || defined ( __OS2__)
#include <io.h>
#include <sys/types.h>
typedef int socklen_t;
#if defined (__OS2__)
#include <netinet/in.h>
#endif
#endif
#ifdef _WIN32
#include <winsock.h>
#define close closesocket
#else
#include <arpa/inet.h> // inet_addr(),...
#endif
#ifndef SOCKET
#define SOCKET u_int
#endif
// ================================ DEFINITIONS ===============================
#define PACKET_SIZE 1024
#define MAX_CLIENT 512
#ifndef _WIN32
#define NO_ERROR 0
#define SOCKET_ERROR -201
#endif
#define BIND_ERROR -202
#define CONNECT_ERROR -203
#define LISTEN_ERROR -204
#define ACCEPT_ERROR -205
#define WRITE_ERROR -210
#define READ_ERROR -211
#define CLOSE_ERROR -212
#define GETHOSTBYNAME_ERROR -220
#define SELECT_ERROR -230
#define TIMEOUT_ERROR -231
#define MALLOC_ERROR -301
#define INVALID_MSG -1
#define ACCEPT_MSG 100
#define ADD_SERVER_MSG 101
#define ADD_CLIENT_MSG 102
#define REMOVE_SERVER_MSG 103
#define ADD_SERVERv2_MSG 104
#define GET_SERVER_MSG 200
#define SEND_SERVER_MSG 201
#define GET_LOGFILE_MSG 202
#define SEND_FILE_MSG 203
#define ERASE_LOGFILE_MSG 204
#define GET_SHORT_SERVER_MSG 205
#define SEND_SHORT_SERVER_MSG 206
#define ASK_SERVER_MSG 206
#define ANSWER_ASK_SERVER_MSG 207
#define GET_MOTD_MSG 208
#define SEND_MOTD_MSG 209
#define GET_ROOMS_MSG 210
#define SEND_ROOMS_MSG 211
#define GET_ROOMS_HOST_MSG 212
#define GET_VERSION_MSG 213
#define SEND_VERSION_MSG 214
#define GET_BANNED_MSG 215
#define PING_SERVER_MSG 216
#define UDP_RECV_MSG 300
#define TIMEOUT_MSG 301
#define HTTP_REQUEST_MSG 875770417 // "4321"
#define SEND_HTTP_REQUEST_MSG 875770418 // "4322"
#define TEXT_REQUEST_MSG 825373494 // "1236"
#define SEND_TEXT_REQUEST_MSG 825373495 // "1237"
#define RSS92_REQUEST_MSG 825373496 // "1238"
#define SEND_RSS92_REQUEST_MSG 825373497 // "1239"
#define RSS10_REQUEST_MSG 825373744 // "1240"
#define SEND_RSS10_REQUEST_MSG 825373745 // "1241"
#define ADD_PSERVER_MSG 0xabacab81 // this number just need to be different than the others
#define REMOVE_PSERVER_MSG 0xabacab82
// Sent FROM Client
#define LIVE_AUTH_USER 600
#define LIVE_AUTH_KEY 601
#define LIVE_GET_USER 602
#define LIVE_UPDATE_LOCATION 603
#define LIVE_UPDATE_PUBLIC_KEY 604
#define LIVE_AUTH_PUBLIC_KEY 605
// Sent TO Client
#define LIVE_INVALID_KEY 800
#define LIVE_INVALID_USER 801
#define LIVE_AUTHORISED_KEY 802
#define LIVE_SEND_USER 803
#define LIVE_VALIDATED_USER 804
// Location Types
#define LIVE_LOCATION_SP 100
#define LIVE_LOCATION_MENU 101
#define LIVE_LOCATION_MP_JOIN 102
#define LIVE_LOCATION_MP_HOST 103
#define LIVE_LOCATION_MP_LOCAL 104
#define LIVE_LOCATION_MP_PRIVATE 105
#define HEADER_SIZE ((UINT32)sizeof (UINT32)*4)
#define HEADER_MSG_POS 0
#define IP_MSG_POS 16
#define PORT_MSG_POS 32
#define HOSTNAME_MSG_POS 40
#if defined(_MSC_VER)
#pragma pack(1)
#endif
// Keep this structure 8 bytes aligned (current size is 80)
typedef struct
{
char header[16]; // information such as password
char ip[16];
char port[8];
char name[32];
INT32 room;
char key[32]; // Secret key for linking dedicated servers to accounts
char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31)
} ATTRPACK msg_server_t;
typedef struct
{
char header[16];
UINT32 id;
char name[32];
char motd[256];
} ATTRPACK msg_rooms_t;
typedef struct
{
char header[16];
char ipstart[16];
char ipend[16];
char endstamp[32];
char reason[256];
UINT8 hostonly;
} ATTRPACK msg_ban_t;
typedef struct
{
char header[16];
INT32 id;
char username[100];
char password[32];
} ATTRPACK msg_live_auth_t;
typedef struct
{
char header[16];
INT32 uid;
char username[100];
INT32 location_type;
char location_ip[32];
INT32 location_port;
INT32 lastseen_type;
char lastseen_data1[256];
char lastseen_data2[256];
char lastseen_data3[256];
} ATTRPACK msg_live_user_t;
typedef struct
{
char header[16];
UINT8 location_type;
char location_ip[32];
INT32 location_port;
char location_data1[256];
char location_data2[256];
char location_data3[256];
} ATTRPACK msg_live_updatelocation_t;
typedef struct
{
char header[16];
char publickey[256];
char username[256];
} ATTRPACK msg_live_validateuser_t;
typedef struct
{
char header[16];
char username[256];
UINT8 keytype;
char keydata[256];
} ATTRPACK msg_live_update_key_t;
typedef struct
{
UINT32 id;
INT32 type;
INT32 room;
INT32 length;
char buffer[PACKET_SIZE];
} ATTRPACK msg_t;
#if defined(_MSC_VER)
#pragma pack()
#endif
class CSocket
{
protected:
sockaddr_in addr;
msg_t msg;
fd_set rset;
public:
int getIP(const char *);
CSocket();
~CSocket();
};
class CServerSocket : public CSocket
{
private:
sockaddr_in udp_addr;
sockaddr_in udp_in_addr;
SOCKET udp_fd;
SOCKET accept_fd;
size_t num_clients;
SOCKET client_fd[MAX_CLIENT];
sockaddr_in client_addr[MAX_CLIENT];
public:
int deleteClient(size_t id);
int listen(const char *str_port);
int accept(void);
int read(msg_t *msg);
const char *getUdpIP(void);
const char *getUdpPort(bool);
int write(msg_t *msg);
int writeUDP(const char *data, size_t length, const char *ip, UINT16 port);
const char *getClientIP(size_t id);
const char *getClientPort(size_t id);
CServerSocket(void);
~CServerSocket(void);
};
class CClientSocket : public CSocket
{
private:
SOCKET socket_fd;
public:
int connect(const char *ip_addr, const char *str_port);
int read(msg_t *msg);
int write(msg_t *msg);
CClientSocket(void);
~CClientSocket(void);
};
// ================================== PROTOS ==================================
// ================================== EXTERNS =================================
#endif

48
masterserver.sh Normal file
View file

@ -0,0 +1,48 @@
#!/bin/sh -e
#
# SRB2 MasterServer - start up the masterserver
#
# Get LSB functions
. /lib/lsb/init-functions
. /etc/default/rcS
SRB2MS=/usr/local/bin/masterserver
SRB2MS_PORT=28900
# Check that the package is still installed
[ -x $SRB2MS ] || exit 0;
case "$1" in
start)
log_begin_msg "Starting SRB2MS..."
umask 002
if start-stop-daemon --start \
--exec $SRB2MS \
-- $SRB2MS_PORT; then
log_end_msg 0
else
log_end_msg $?
fi
;;
stop)
log_begin_msg "Stopping SRB2MS..."
if start-stop-daemon --stop --exec $SRB2MS; then
log_end_msg 0
else
log_end_msg $?
fi
;;
restart|force-reload)
"$0" stop && "$0" start
;;
*)
e cho "Usage: /etc/init.d/masterserver {start|stop|restart|force-reload}"
exit 1
;;
esac
exit 0

363
md5.cpp Normal file
View file

@ -0,0 +1,363 @@
/* MD5
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
for bzflag (http://www.bzflag.org)
based on:
md5.h and md5.c
reference implemantion of RFC 1321
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* interface header */
#include "md5.h"
/* system implementation headers */
#include <stdio.h>
#include <string.h>
// Constants for MD5Transform routine.
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
///////////////////////////////////////////////
// F, G, H and I are basic MD5 functions.
inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
return (x&y) | (~x&z);
}
inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
return (x&z) | (y&~z);
}
inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
return x^y^z;
}
inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
return y ^ (x | ~z);
}
// rotate_left rotates x left n bits.
inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
return (x << n) | (x >> (32-n));
}
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a+ F(b,c,d) + x + ac, s) + b;
}
inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + G(b,c,d) + x + ac, s) + b;
}
inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + H(b,c,d) + x + ac, s) + b;
}
inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + I(b,c,d) + x + ac, s) + b;
}
//////////////////////////////////////////////
// default ctor, just initailize
MD5::MD5()
{
init();
}
//////////////////////////////////////////////
// nifty shortcut ctor, compute MD5 for string and finalize it right away
MD5::MD5(const std::string &text)
{
init();
update(text.c_str(), text.length());
finalize();
}
//////////////////////////////
void MD5::init()
{
finalized=false;
count[0] = 0;
count[1] = 0;
// load magic initialization constants.
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
}
//////////////////////////////
// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
void MD5::decode(uint4 output[], const uint1 input[], size_type len)
{
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
}
//////////////////////////////
// encodes input (uint4) into output (unsigned char). Assumes len is
// a multiple of 4.
void MD5::encode(uint1 output[], const uint4 input[], size_type len)
{
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
output[j] = input[i] & 0xff;
output[j+1] = (input[i] >> 8) & 0xff;
output[j+2] = (input[i] >> 16) & 0xff;
output[j+3] = (input[i] >> 24) & 0xff;
}
}
//////////////////////////////
// apply MD5 algo on a block
void MD5::transform(const uint1 block[blocksize])
{
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
decode (x, block, blocksize);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
// Zeroize sensitive information.
memset(x, 0, sizeof x);
}
//////////////////////////////
// MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block
void MD5::update(const unsigned char input[], size_type length)
{
// compute number of bytes mod 64
size_type index = count[0] / 8 % blocksize;
// Update number of bits
if ((count[0] += (length << 3)) < (length << 3))
count[1]++;
count[1] += (length >> 29);
// number of bytes we need to fill in buffer
size_type firstpart = 64 - index;
size_type i;
// transform as many times as possible.
if (length >= firstpart)
{
// fill buffer first, transform
memcpy(&buffer[index], input, firstpart);
transform(buffer);
// transform chunks of blocksize (64 bytes)
for (i = firstpart; i + blocksize <= length; i += blocksize)
transform(&input[i]);
index = 0;
}
else
i = 0;
// buffer remaining input
memcpy(&buffer[index], &input[i], length-i);
}
//////////////////////////////
// for convenience provide a verson with signed char
void MD5::update(const char input[], size_type length)
{
update((const unsigned char*)input, length);
}
//////////////////////////////
// MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context.
MD5& MD5::finalize()
{
static unsigned char padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (!finalized) {
// Save number of bits
unsigned char bits[8];
encode(bits, count, 8);
// pad out to 56 mod 64.
size_type index = count[0] / 8 % 64;
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
update(padding, padLen);
// Append length (before padding)
update(bits, 8);
// Store state in digest
encode(digest, state, 16);
// Zeroize sensitive information.
memset(buffer, 0, sizeof buffer);
memset(count, 0, sizeof count);
finalized=true;
}
return *this;
}
//////////////////////////////
// return hex representation of digest as string
std::string MD5::hexdigest() const
{
if (!finalized)
return "";
char buf[33];
for (int i=0; i<16; i++)
sprintf(buf+i*2, "%02x", digest[i]);
buf[32]=0;
return std::string(buf);
}
//////////////////////////////
std::ostream& operator<<(std::ostream& out, MD5 md5)
{
return out << md5.hexdigest();
}
//////////////////////////////
std::string md5(const std::string str)
{
MD5 md5 = MD5(str);
return md5.hexdigest();
}

93
md5.h Normal file
View file

@ -0,0 +1,93 @@
/* MD5
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
for bzflag (http://www.bzflag.org)
based on:
md5.h and md5.c
reference implementation of RFC 1321
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#ifndef BZF_MD5_H
#define BZF_MD5_H
#include <string>
#include <iostream>
// a small class for calculating MD5 hashes of strings or byte arrays
// it is not meant to be fast or secure
//
// usage: 1) feed it blocks of uchars with update()
// 2) finalize()
// 3) get hexdigest() string
// or
// MD5(std::string).hexdigest()
//
// assumes that char is 8 bit and int is 32 bit
class MD5
{
public:
typedef unsigned int size_type; // must be 32bit
MD5();
MD5(const std::string& text);
void update(const unsigned char *buf, size_type length);
void update(const char *buf, size_type length);
MD5& finalize();
std::string hexdigest() const;
friend std::ostream& operator<<(std::ostream&, MD5 md5);
private:
void init();
typedef unsigned char uint1; // 8bit
typedef unsigned int uint4; // 32bit
enum {blocksize = 64}; // VC6 won't eat a const static int here
void transform(const uint1 block[blocksize]);
static void decode(uint4 output[], const uint1 input[], size_type len);
static void encode(uint1 output[], const uint4 input[], size_type len);
bool finalized;
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
uint4 state[4]; // digest so far
uint1 digest[16]; // the result
// low level logic operations
static inline uint4 F(uint4 x, uint4 y, uint4 z);
static inline uint4 G(uint4 x, uint4 y, uint4 z);
static inline uint4 H(uint4 x, uint4 y, uint4 z);
static inline uint4 I(uint4 x, uint4 y, uint4 z);
static inline uint4 rotate_left(uint4 x, int n);
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
};
std::string md5(const std::string str);
#endif

1037
server.cpp Normal file

File diff suppressed because it is too large Load diff

405
srvlist.cpp Normal file
View file

@ -0,0 +1,405 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#ifdef __GNUC__
#include <unistd.h>
#endif
#include <typeinfo>
#include "common.h"
#include "srvlist.h"
//=============================================================================
/*
**
*/
CList::CList()
{
list = NULL;
current = NULL;
}
/*
**
*/
CList::~CList()
{
CItem *p;
while (list)
{
p = list;
list = list->next;
delete(p);
}
}
/*
**
*/
int CList::insert(CItem *item)
{
item->next = list;
list = item;
return 0;
}
/*
**
*/
int CList::remove(CItem *item)
{
CItem *position, *q;
q = NULL;
position = list;
while (position && (position != item))
{
q = position;
position = position->next;
}
if (position)
{
if (q)
q->next = position->next;
else
list = position->next;
delete position;
return 1;
}
return 0;
}
/*
**
*/
CItem *CList::getFirst()
{
current = list;
return current;
}
/*
**
*/
CItem *CList::getNext()
{
if (current)
current = current->next;
return current;
}
/*
**
*/
void CList::show()
{
CItem *p;
p = list;
while (p)
{
p->print();
p = p->next;
}
}
//=============================================================================
/*
**
*/
CItem::CItem()
{
next = NULL;
}
//=============================================================================
/*
**
*/
CInetAddr::CInetAddr(const char *ip, const char *port)
{
strcpy(this->ip, ip);
strcpy(this->port, port);
PortNotChanged = true;
}
/*
**
*/
const char *CInetAddr::getIP()
{
return ip;
}
/*
**
*/
const char *CInetAddr::getPort()
{
return port;
}
/*
**
*/
bool CInetAddr::setPort(const char *port)
{
if (PortNotChanged)
{
strcpy(this->port, port);
PortNotChanged = false;
}
return !PortNotChanged;
}
//=============================================================================
/*
**
*/
CPlayerItem::CPlayerItem(const char *ip, const char *port,
const char *nickname) : CInetAddr(ip, port)
{
strcpy(this->nickname, nickname);
}
/*
**
*/
void CPlayerItem::print()
{
dbgPrintf(GREEN, "\tIP\t\t: %s\n\tPort\t\t: %s\n\tNickname\t: %s\n",
ip, port, nickname);
}
/*
**
*/
char *CPlayerItem::getString()
{
static char tmpbuf[1024];
snprintf(tmpbuf, sizeof tmpbuf,
"\tIP\t\t: %s\n\tPort\t\t: %s\n\tNickname\t: %s\n",
ip, port, nickname);
return tmpbuf;
}
//=============================================================================
/*
**
*/
CServerItem::CServerItem(const char *ip, const char *port, const char *hostname, const char *version, ServerType type) : CInetAddr(ip, port)
{
time_t timenow = time(NULL);
const tm *timeGMT = gmtime(&timenow);
// check name of server here
strcpy(this->hostname, hostname);
strcpy(this->version, version);
this->type = type;
strftime(reg_time, REG_TIME_SIZE+1, "%Y-%m-%dT%H:%MZ",timeGMT);
{
int i;
memset(guid,'\0',GUID_SIZE);
strcpy(&guid[0], ip);
strcpy(&guid[15], port); // GenUID
for (i = 0; i <= GUID_SIZE-1; i++)
{
if (guid[i] == '\0' || guid[i] == '.')
guid[i] = '0' + (rand()/(RAND_MAX/15));
if (guid[i] > '9')
guid[i] += 'A'-'9';
}
guid[GUID_SIZE] = '\0';
}
HeartBeat = time(NULL);
}
/*
**
*/
void CServerItem::print()
{
dbgPrintf(GREEN, "IP\t\t: %s\nPort\t\t: %s\nHostname\t: %s\nVersion\t: %s\nPermanent\t: %s\n",
ip, port, hostname, version, (type == ST_PERMANENT) ? "Yes" : "No");
}
/*
**
*/
const char *CServerItem::getString()
{
static char tmpbuf[1024];
snprintf(tmpbuf, sizeof tmpbuf,
"IP\t\t: %s\nPort\t\t: %s\nHostname\t: %s\nVersion\t\t: %s\nPermanent\t: %s\n",
ip, port, hostname, version, (type==ST_PERMANENT) ? "Yes" : "No");
return tmpbuf;
}
/*
**
*/
const char *CServerItem::getName()
{
return hostname;
}
/*
**
*/
const char *CServerItem::getVersion()
{
return version;
}
/*
**
*/
const char *CServerItem::getGuid()
{
return guid;
}
/*
**
*/
const char *CServerItem::getRegtime()
{
return reg_time;
}
/*
**
*/
//=============================================================================
/*
**
*/
void CServerList::insertPlayer(CServerItem *server, CPlayerItem *player)
{
server->players_list.insert(player);
}
/*
**
*/
void CServerList::removePlayer(CServerItem *server, CPlayerItem *player)
{
server->players_list.remove(player);
}
/*
**
*/
int CServerList::insert(CServerItem *server)
{
CList::insert((CItem *)server);
return 0;
}
/*
**
*/
int CServerList::insert(const char *ip, const char *port,
const char *hostname, const char *version, ServerType type)
{
CServerItem *server;
server = new CServerItem(ip, port, hostname, version, type);
CList::insert(server);
return 0;
}
/*
**
*/
int CServerList::remove(CServerItem *server)
{
return CList::remove((CItem *)server);
}
/*
**
*/
int CServerList::remove(const char *ip, const char *port,
const char *hostname, const char *version, ServerType type)
{
// TODO
CServerItem *position, *q;
bool match;
(void)hostname;
(void)port;
match = false;
position = (CServerItem *)list;
q = NULL;
while (position && !match)
{
if (strcmp(position->ip, ip) == 0
&& strcmp(position->version, version) == 0
&& strcmp(position->port, port) == 0
&& position->type == type)
{
match = true;
}
else
{
q = position;
position = (CServerItem *)position->next;
}
}
if (position && match)
{
if (q)
q->next = position->next;
else
list = position->next;
delete position;
return 1;
}
return 0;
}
/*
**
*/
void CServerList::show()
{
CServerItem *p;
p = (CServerItem *)list;
while (p)
{
p->print();
p->players_list.show();
p = (CServerItem *)p->next;
}
}

136
srvlist.h Normal file
View file

@ -0,0 +1,136 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#ifndef SRVLIST_H
#define SRVLIST_H
#include <time.h>
enum ServerType
{
ST_PERMANENT = 0,
ST_TEMPORARY,
};
//=============================================================================
class CItem
{
friend class CList;
protected:
CItem *next;
public:
CItem();
virtual ~CItem() {}; // destructor must exist and be virtual
virtual void print() = 0;
};
//=============================================================================
class CList
{
protected:
CItem *list;
CItem *current; // the current item we are pointing on (for getfirst/getnext)
public:
CList();
virtual ~CList();
int insert(CItem *);
int remove(CItem *);
CItem *getFirst();
CItem *getNext();
void show();
};
//=============================================================================
class CInetAddr
{
protected:
char ip[16];
char port[8];
bool PortNotChanged;
public:
CInetAddr(const char *ip, const char *port);
const char *getIP();
bool setPort(const char *port);
const char *getPort();
};
//=============================================================================
class CPlayerItem : public CItem, public CInetAddr
{
friend class CPlayerList;
private:
char nickname[32];
public:
CPlayerItem(const char *ip, const char *port, const char *nickname);
void print();
char *getString();
};
//=============================================================================
class CPlayerList : public CList
{
};
//=============================================================================
#define REG_TIME_SIZE 24 //1970-00-00T00:00:00.0+00:00
#define GUID_SIZE 24-1 // format is 12700000000105000
class CServerItem : public CItem, public CInetAddr
{
friend class CServerList;
private:
char hostname[32];
char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31)
CPlayerList players_list;
char reg_time[REG_TIME_SIZE];
char guid[GUID_SIZE+1];
public:
ServerType type;
time_t HeartBeat;
CServerItem(const char *ip, const char *port, const char *hostname, const char *version, ServerType type);
void print();
const char *getString();
const char *getName();
const char *getVersion();
const char *getRegtime();
const char *getGuid();
};
//=============================================================================
class CServerList : public CList
{
public:
void insertPlayer(CServerItem *server, CPlayerItem *player);
void removePlayer(CServerItem *server, CPlayerItem *player);
int insert(const char *ip, const char *port, const char *hostname, const char *version, ServerType type);
int insert(CServerItem *server);
int remove(const char *ip, const char *port, const char *hostname, const char *version, ServerType type);
int remove(CServerItem *server);
void show();
};
#endif

147
stats.cpp Normal file
View file

@ -0,0 +1,147 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#ifdef __GNUC__
#include <unistd.h>
#endif
#include <string.h> // strcat(),...
#include "common.h"
#include "ipcs.h"
#include "stats.h"
//=============================================================================
/*
** CServerStats()
*/
CServerStats::CServerStats()
{
uptime = time(NULL);
num_connections = 0;
num_http_con = 0;
num_servers = 0;
snprintf(motd, sizeof motd, "%s%s", "Welcome to the SRB2 Master Server!<br>", SERVERMOTDTEXT);
num_add = 0;
num_removal = 0;
num_retrieval = 0;
num_autoremoval = 0;
num_badconnection = 0;
for (int i = 0; i < NUMLASTSERVERS; i++)
{
strcpy(last_server[i].ip, "0.0.0.0");
strcpy(last_server[i].name, "Non-Existing SRB2 server");
strcpy(last_server[i].version, "0.0.0");
}
snprintf(version, sizeof version, "%s %s", __DATE__, __TIME__);
}
/*
** ~CServerStats()
*/
CServerStats::~CServerStats()
{
}
/*
** getUptime()
*/
const char *CServerStats::getUptime()
{
char *res = ctime(&uptime);
res[strlen(res)-1] = '\0'; // remove the '\n' at the end
return res;
}
/*
** getHours()
*/
int CServerStats::getHours()
{
return (int)(((time(NULL) - uptime)/(60*60))%24);
}
/*
** getDays()
*/
int CServerStats::getDays()
{
return (int)((time(NULL) - uptime)/(60*60*24));
}
/*
** getMotd()
*/
const char *CServerStats::getMotd()
{
return motd;
}
/*
** getLastServers()
*/
const char *CServerStats::getLastServers()
{
static char res[170*NUMLASTSERVERS];
tzset();
res[0] = '\0';
for (int i = 0; i < NUMLASTSERVERS; i++)
{
char str[170];
char *ct;
ct = ctime(&last_time[i]);
ct[strlen(ct)-1] = '\0'; // replace \n with a \0
snprintf(str, sizeof str,
"Address: %15s Name: %-31s v%-7s (%s %s)\n000043210000",
last_server[i].ip, last_server[i].name, last_server[i].version, ct, tzname[0]);
strcat(res, str);
}
return res;
}
/*
** getVersion()
*/
const char *CServerStats::getVersion()
{
return version;
}
/*
** putMotd()
*/
void CServerStats::putMotd(char *motd)
{
strcpy(this->motd, motd);
}
/*
** putLastServer():
*/
void CServerStats::putLastServer(msg_server_t *server)
{
for (int i = NUMLASTSERVERS-1; i > 0; i--)
{
memcpy(&last_server[i], &last_server[i-1],
sizeof (msg_server_t));
last_time[i] = last_time[i-1];
}
memcpy(&last_server[0], server, sizeof (msg_server_t));
last_time[0] = time(NULL);
}

68
stats.h Normal file
View file

@ -0,0 +1,68 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 2000 by DooM Legacy Team.
//
// 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.
//
//-----------------------------------------------------------------------------
#ifndef _STATS_H_
#define _STATS_H_
#ifndef _IPCS_H_
#error "You forget to include ipcs.h"
#endif
#include <time.h>
#define NUMLASTSERVERS 6
#define SERVERMOTDTEXT "No Clans, advertising websites, Chat, Hangout, Hacked, or Role Playing Servers Allowed"
// ================================ DEFINITIONS ===============================
class CServerStats
{
time_t uptime; // master server uptime
char motd[2048]; // increase that if not enough
msg_server_t last_server[NUMLASTSERVERS]; // keep last 6 named registered servers
time_t last_time[NUMLASTSERVERS]; // keep date/time of registration of those servers
char version[32]; // master server version
public:
int num_connections;
int num_http_con;
int num_text_con;
int num_RSS92_con;
int num_RSS10_con;
int num_servers;
int num_add;
int num_removal;
int num_retrieval;
int num_autoremoval;
int num_badconnection;
CServerStats();
~CServerStats();
const char *getUptime();
int getHours();
int getDays();
const char *getMotd();
const char *getLastServers();
const char *getVersion();
void putMotd(char *);
void putLastServer(msg_server_t *);
};
// ================================== PROTOS ==================================
// ================================== EXTERNS =================================
#endif