rewrite
This commit is contained in:
Anonymous275 2020-08-21 20:58:10 +03:00
parent 232c4d7b28
commit 31c96cee94
59 changed files with 4247 additions and 1212 deletions

2
.idea/.name generated
View File

@ -1 +1 @@
BeamMP-Server
Server

View File

@ -1,16 +1,8 @@
cmake_minimum_required(VERSION 3.15)
project(BeamMP-Server)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2")
include_directories(${PROJECT_SOURCE_DIR}/curl)
cmake_minimum_required(VERSION 3.10)
project(Server)
set(CMAKE_CXX_STANDARD 17)
file(GLOB source_files
"src/*.h" "src/*.hpp" "src/*.cpp"
"src/Network 2.0/*.hpp" "src/Network 2.0/*.cpp"
"src/Lua System/*.hpp" "src/Lua System/*.cpp"
"src/curl/*.h" "src/lua/*.h" "src/lua/*.hpp")
add_executable(BeamMP-Server ${source_files})
target_link_libraries(BeamMP-Server libcurl_a ws2_32 lua53)
file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "include/*.h" "include/*/*.h" "include/*.hpp" "include/*/*.hpp")
add_executable(${PROJECT_NAME} ${source_files})
target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "BeamMP-Server")
target_link_libraries(${PROJECT_NAME} libcurl_a urlmon ws2_32 lua53 zlibstatic)

View File

@ -9,20 +9,22 @@
#include <chrono>
#include <set>
struct VData{
int ID = -1;
std::string Data;
};
class Client {
private:
std::set<std::pair<int,std::string>> VehicleData; //ID and Data;
std::set<VData*> VehicleData; //ID and Data;
std::string Name = "Unknown Client";
bool Connected = false;
sockaddr_in UDPADDR;
std::string Role;
std::string DID; //Discord ID
std::string DID;
SOCKET TCPSOCK;
int Status = 0;
int ID = -1; //PlayerID
int ID = -1;
public:
bool isDownloading = true;
std::set<std::pair<int,std::string>> GetAllCars();
void AddNewCar(int ident,const std::string& Data);
void SetCarData(int ident,const std::string&Data);
void SetName(const std::string& name);
@ -30,21 +32,37 @@ public:
void SetDID(const std::string& did);
std::string GetCarData(int ident);
void SetUDPAddr(sockaddr_in Addr);
std::set<VData*> GetAllCars();
void SetTCPSock(SOCKET CSock);
void SetConnected(bool state);
void SetStatus(int status);
void DeleteCar(int ident);
sockaddr_in GetUDPAddr();
bool isConnected = false;
std::string GetRole();
std::string GetName();
bool isSynced = false;
std::string GetDID();
SOCKET GetTCPSock();
bool isConnected();
void SetID(int ID);
int GetCarCount();
int GetOpenCarID();
int GetCarCount();
void ClearCars();
int GetStatus();
int GetID();
};
struct ClientInterface{
std::set<Client*> Clients;
void RemoveClient(Client *c){
Clients.erase(c);
delete c;
c = nullptr;
}
void AddClient(Client *c){
Clients.insert(c);
}
int Size(){
return int(Clients.size());
}
};
extern std::set<Client*> Clients;
extern ClientInterface* CI;

7
include/Compressor.h Normal file
View File

@ -0,0 +1,7 @@
///
/// Created by Anonymous275 on 7/24/2020
///
#pragma once
#include <string>
std::string Comp(std::string Data);
std::string DeComp(std::string Compressed);

7
include/Curl/Http.h Normal file
View File

@ -0,0 +1,7 @@
///
/// Created by Anonymous275 on 7/18/2020
///
#pragma once
#include <string>
std::string HttpRequest(const std::string& IP,int port);
std::string PostHTTP(const std::string& IP,const std::string& Fields);

View File

@ -60,8 +60,8 @@
defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
/* The check above prevents the winsock2 inclusion if winsock.h already was
included, since they can't co-exist without problems */
#include <winsock2.h>
#include <ws2tcpip.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif
#endif

View File

@ -581,7 +581,7 @@ typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
#ifdef HEADER_SSL_H
/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
/* hTRG: if we included OpenSSL's ssl.h, we know about SSL_CTX
* this will of course break if we're included before OpenSSL headers...
*/
typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);

View File

@ -1,16 +1,12 @@
///
/// Created by Anonymous275 on 4/2/2020.
///
#include <ctime>
#include <sstream>
#pragma once
#include <string>
#include <iostream>
extern int loggerlevel;
std::stringstream getDate();
void setLoggerLevel(int level);
void InitLog();
void except(const std::string& toPrint);
void debug(const std::string& toPrint);
void error(const std::string& toPrint);
void info(const std::string& toPrint);
void warn(const std::string& toPrint);
void error(const std::string& toPrint);
void debug(const std::string& toPrint);
void Exception(unsigned long Code,char* Origin);

View File

@ -3,14 +3,14 @@
///
#pragma once
#include <filesystem>
#include <iostream>
#include "lua.hpp"
#include <vector>
#include <thread>
#include <set>
#include <any>
#include <thread>
#include <vector>
#include <iostream>
#include <filesystem>
#include "../lua/lua.hpp"
namespace fs = std::filesystem;
namespace fs = std::experimental::filesystem;
struct LuaArg{
std::vector<std::any> args;
void PushArgs(lua_State *State){
@ -43,7 +43,6 @@ private:
public:
void RegisterEvent(const std::string&Event,const std::string&FunctionName);
int CallFunction(const std::string& FuncName,LuaArg* args);
std::string GetRegistered(const std::string&Event);
void UnRegisterEvent(const std::string&Event);
void SetLastWrite(fs::file_time_type time);
@ -51,13 +50,17 @@ public:
void SetPluginName(const std::string&Name);
void SetFileName(const std::string&Name);
fs::file_time_type GetLastWrite();
bool isThreadExecuting = false;
std::string GetPluginName();
std::string GetFileName();
bool isExecuting = false;
bool StopThread = false;
bool HasThread = false;
lua_State* GetState();
char* GetOrigin();
void Reload();
void Init();
};
int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* args);
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg);
extern std::set<Lua*> PluginEngine;

19
include/Network.h Normal file
View File

@ -0,0 +1,19 @@
///
/// Created by Anonymous275 on 7/31/2020
///
#pragma once
#include "Client.hpp"
#include <string>
void TCPServerMain();
void UpdatePlayers();
void OnConnect(Client*c);
void InitClient(Client*c);
void SyncResources(Client*c);
[[noreturn]] void UDPServerMain();
void OnDisconnect(Client*c,bool kicked);
void UDPSend(Client*c,std::string Data);
void TCPSend(Client*c,const std::string&Data);
void SendLarge(Client*c,const std::string&Data);
void GParser(Client*c, const std::string&Packet);
void Respond(Client*c, const std::string& MSG, bool Rel);
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel);

16
include/Security/Enc.h Normal file
View File

@ -0,0 +1,16 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#pragma once
#include <WS2tcpip.h>
#include <string>
#include "Xor.h"
struct RSA{
int n = 0;
int e = 0;
int d = 0;
};
std::string RSA_E(const std::string& Data, RSA*k);
std::string RSA_D(const std::string& Data, RSA*k);
int Handle(EXCEPTION_POINTERS *ep,char* Origin);
RSA* GenKey();

130
include/Security/Xor.h Normal file
View File

@ -0,0 +1,130 @@
///
/// Created by Anonymous275 on 8/11/2020
///
#pragma once
#include <string>
#include <array>
#include <cstdarg>
#define BEGIN_NAMESPACE(x) namespace x {
#define END_NAMESPACE }
BEGIN_NAMESPACE(XorCompileTime)
constexpr auto time = __TIME__;
constexpr auto seed = static_cast<int>(time[7]) + static_cast<int>(time[6]) * 10 + static_cast<int>(time[4]) * 60 + static_cast<int>(time[3]) * 600 + static_cast< int >(time[1]) * 3600 + static_cast< int >(time[0]) * 36000;
// 1988, Stephen Park and Keith Miller
// "Random Number Generators: Good Ones Are Hard To Find", considered as "minimal standard"
// Park-Miller 31 bit pseudo-random number generator, implemented with G. Carta's optimisation:
// with 32-bit math and without division
template <int N>
struct RandomGenerator{
private:
static constexpr unsigned a = 16807; // 7^5
static constexpr unsigned m = 2147483647; // 2^31 - 1
static constexpr unsigned s = RandomGenerator< N - 1 >::value;
static constexpr unsigned lo = a * (s & 0xFFFFu); // Multiply lower 16 bits by 16807
static constexpr unsigned hi = a * (s >> 16u); // Multiply higher 16 bits by 16807
static constexpr unsigned lo2 = lo + ((hi & 0x7FFFu) << 16u); // Combine lower 15 bits of hi with lo's upper bits
static constexpr unsigned hi2 = hi >> 15u; // Discard lower 15 bits of hi
static constexpr unsigned lo3 = lo2 + hi;
public:
static constexpr unsigned max = m;
static constexpr unsigned value = lo3 > m ? lo3 - m : lo3;
};
template <>
struct RandomGenerator< 0 >{
static constexpr unsigned value = seed;
};
template <int N, int M>
struct RandomInt{
static constexpr auto value = RandomGenerator< N + 1 >::value % M;
};
template <int N>
struct RandomChar{
static const char value = static_cast< char >(1 + RandomInt< N, 0x7F - 1 >::value);
};
template <size_t N, int K, typename Char>
struct XorString{
private:
const char _key;
std::array< Char, N + 1 > _encrypted;
constexpr Char enc(Char c) const{
return c ^ _key;
}
Char dec(Char c) const{
return c ^ _key;
}
public:
template <size_t... Is>
constexpr __forceinline XorString(const Char* str, std::index_sequence< Is... >) : _key(RandomChar< K >::value), _encrypted{ enc(str[Is])... }
{}
__forceinline decltype(auto) decrypt(){
for (size_t i = 0; i < N; ++i) {
_encrypted[i] = dec(_encrypted[i]);
}
_encrypted[N] = '\0';
return _encrypted.data();
}
};
static auto w_printf = [](const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf_s(fmt, args);
va_end(args);
};
static auto w_printf_s = [](const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf_s(fmt, args);
va_end(args);
};
/*static auto w_sprintf = [](char* buf, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
};*/
/*static auto w_sprintf_ret = [](char* buf, const char* fmt, ...) {
int ret;
va_list args;
va_start(args, fmt);
ret = vsprintf(buf, fmt, args);
va_end(args);
return ret;
};*/
static auto w_sprintf_s = [](char* buf, size_t buf_size, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vsprintf_s(buf, buf_size, fmt, args);
va_end(args);
};
static auto w_sprintf_s_ret = [](char* buf, size_t buf_size, const char* fmt, ...) {
int ret;
va_list args;
va_start(args, fmt);
ret = vsprintf_s(buf, buf_size, fmt, args);
va_end(args);
return ret;
};
#define Sec( s ) []{ constexpr XorCompileTime::XorString< sizeof(s)/sizeof(char) - 1, __COUNTER__, char > expr( s, std::make_index_sequence< sizeof(s)/sizeof(char) - 1>() ); return expr; }().decrypt()
#define SecW( s ) []{ constexpr XorCompileTime::XorString< sizeof(s)/sizeof(wchar_t) - 1, __COUNTER__, wchar_t > expr( s, std::make_index_sequence< sizeof(s)/sizeof(wchar_t) - 1>() ); return expr; }().decrypt()
END_NAMESPACE

View File

@ -1,8 +1,8 @@
///
/// Created by Anonymous275 on 4/10/2020
/// Created by Anonymous275 on 7/28/2020
///
extern std::string ServerVersion;
extern std::string ClientVersion;
#pragma once
#include <string>
extern std::string ServerName;
extern std::string ServerDesc;
extern std::string StatReport;
@ -11,12 +11,14 @@ extern std::string Resource;
extern std::string FileList;
extern std::string CustomIP;
extern std::string MapName;
extern uint64_t MaxModSize;
extern std::string Key;
std::string GetSVer();
std::string GetCVer();
extern int MaxPlayers;
extern int ModsLoaded;
extern int Beat;
extern long MaxModSize;
extern bool Private;
extern int MaxCars;
extern bool Debug;
extern int Port;
extern int PPS;

11
include/Startup.h Normal file
View File

@ -0,0 +1,11 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#pragma once
void InitServer(int argc, char* argv[]);
void InitConfig();
void InitLua();
void InitRes();
void HBInit();
void StatInit();
void NetMain();

536
include/Zlib/zconf.h Normal file
View File

@ -0,0 +1,536 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/* #undef Z_PREFIX */
/* #undef Z_HAVE_UNISTD_H */
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
* Even better than compiling with -DZ_PREFIX would be to use configure to set
* this permanently in zconf.h using "./configure --zprefix".
*/
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
# define Z_PREFIX_SET
/* all linked symbols and init macros */
# define _dist_code z__dist_code
# define _length_code z__length_code
# define _tr_align z__tr_align
# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block
# define _tr_tally z__tr_tally
# define adler32 z_adler32
# define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64
# define adler32_z z_adler32_z
# ifndef Z_SOLO
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# endif
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
# define crc32_z z_crc32_z
# define deflate z_deflate
# define deflateBound z_deflateBound
# define deflateCopy z_deflateCopy
# define deflateEnd z_deflateEnd
# define deflateGetDictionary z_deflateGetDictionary
# define deflateInit z_deflateInit
# define deflateInit2 z_deflateInit2
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset
# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table
# ifndef Z_SOLO
# define gz_error z_gz_error
# define gz_intmax z_gz_intmax
# define gz_strwinerror z_gz_strwinerror
# define gzbuffer z_gzbuffer
# define gzclearerr z_gzclearerr
# define gzclose z_gzclose
# define gzclose_r z_gzclose_r
# define gzclose_w z_gzclose_w
# define gzdirect z_gzdirect
# define gzdopen z_gzdopen
# define gzeof z_gzeof
# define gzerror z_gzerror
# define gzflush z_gzflush
# define gzfread z_gzfread
# define gzfwrite z_gzfwrite
# define gzgetc z_gzgetc
# define gzgetc_ z_gzgetc_
# define gzgets z_gzgets
# define gzoffset z_gzoffset
# define gzoffset64 z_gzoffset64
# define gzopen z_gzopen
# define gzopen64 z_gzopen64
# ifdef _WIN32
# define gzopen_w z_gzopen_w
# endif
# define gzprintf z_gzprintf
# define gzputc z_gzputc
# define gzputs z_gzputs
# define gzread z_gzread
# define gzrewind z_gzrewind
# define gzseek z_gzseek
# define gzseek64 z_gzseek64
# define gzsetparams z_gzsetparams
# define gztell z_gztell
# define gztell64 z_gztell64
# define gzungetc z_gzungetc
# define gzvprintf z_gzvprintf
# define gzwrite z_gzwrite
# endif
# define inflate z_inflate
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define inflateBackInit z_inflateBackInit
# define inflateBackInit_ z_inflateBackInit_
# define inflateCodesUsed z_inflateCodesUsed
# define inflateCopy z_inflateCopy
# define inflateEnd z_inflateEnd
# define inflateGetDictionary z_inflateGetDictionary
# define inflateGetHeader z_inflateGetHeader
# define inflateInit z_inflateInit
# define inflateInit2 z_inflateInit2
# define inflateInit2_ z_inflateInit2_
# define inflateInit_ z_inflateInit_
# define inflateMark z_inflateMark
# define inflatePrime z_inflatePrime
# define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2
# define inflateResetKeep z_inflateResetKeep
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine
# define inflateValidate z_inflateValidate
# define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table
# ifndef Z_SOLO
# define uncompress z_uncompress
# define uncompress2 z_uncompress2
# endif
# define zError z_zError
# ifndef Z_SOLO
# define zcalloc z_zcalloc
# define zcfree z_zcfree
# endif
# define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion
/* all zlib typedefs in zlib.h and zconf.h */
# define Byte z_Byte
# define Bytef z_Bytef
# define alloc_func z_alloc_func
# define charf z_charf
# define free_func z_free_func
# ifndef Z_SOLO
# define gzFile z_gzFile
# endif
# define gz_header z_gz_header
# define gz_headerp z_gz_headerp
# define in_func z_in_func
# define intf z_intf
# define out_func z_out_func
# define uInt z_uInt
# define uIntf z_uIntf
# define uLong z_uLong
# define uLongf z_uLongf
# define voidp z_voidp
# define voidpc z_voidpc
# define voidpf z_voidpf
/* all zlib structs in zlib.h and zconf.h */
# define gz_header_s z_gz_header_s
# define internal_state z_internal_state
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
#if defined(ZLIB_CONST) && !defined(z_const)
# define z_const const
#else
# define z_const
#endif
#ifdef Z_SOLO
typedef unsigned long z_size_t;
#else
# define z_longlong long long
# if defined(NO_SIZE_T)
typedef unsigned NO_SIZE_T z_size_t;
# elif defined(STDC)
# include <stddef.h>
typedef size_t z_size_t;
# else
typedef unsigned long z_size_t;
# endif
# undef z_longlong
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
#ifndef Z_ARG /* function prototypes for stdarg */
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
# define Z_ARG(args) args
# else
# define Z_ARG(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
# include <limits.h>
# if (UINT_MAX == 0xffffffffUL)
# define Z_U4 unsigned
# elif (ULONG_MAX == 0xffffffffUL)
# define Z_U4 unsigned long
# elif (USHRT_MAX == 0xffffffffUL)
# define Z_U4 unsigned short
# endif
#endif
#ifdef Z_U4
typedef Z_U4 z_crc_t;
#else
typedef unsigned long z_crc_t;
#endif
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H
#endif
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_STDARG_H
#endif
#ifdef STDC
# ifndef Z_SOLO
# include <sys/types.h> /* for off_t */
# endif
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
# include <stdarg.h> /* for va_list */
# endif
#endif
#ifdef _WIN32
# ifndef Z_SOLO
# include <stddef.h> /* for wchar_t */
# endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
* though the former does not conform to the LFS document), but considering
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations
*/
#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE
#endif
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
# define Z_HAVE_UNISTD_H
#endif
#ifndef Z_SOLO
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# ifndef z_off_t
# define z_off_t off_t
# endif
# endif
#endif
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
# define Z_LFS64
#endif
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
# define Z_LARGE64
#endif
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
# define Z_WANT64
#endif
#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
# define z_off64_t __int64
# else
# define z_off64_t z_off_t
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
#pragma map(deflateInit_,"DEIN")
#pragma map(deflateInit2_,"DEIN2")
#pragma map(deflateEnd,"DEEND")
#pragma map(deflateBound,"DEBND")
#pragma map(inflateInit_,"ININ")
#pragma map(inflateInit2_,"ININ2")
#pragma map(inflateEnd,"INEND")
#pragma map(inflateSync,"INSY")
#pragma map(inflateSetDictionary,"INSEDI")
#pragma map(compressBound,"CMBND")
#pragma map(inflate_table,"INTABL")
#pragma map(inflate_fast,"INFA")
#pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

1912
include/Zlib/zlib.h Normal file

File diff suppressed because it is too large Load Diff

271
include/Zlib/zutil.h Normal file
View File

@ -0,0 +1,271 @@
/* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id$ */
#ifndef ZUTIL_H
#define ZUTIL_H
#ifdef HAVE_HIDDEN
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
#else
# define ZLIB_INTERNAL
#endif
#include "zlib.h"
#if defined(STDC) && !defined(Z_SOLO)
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
# include <stddef.h>
# endif
# include <string.h>
# include <stdlib.h>
#endif
#ifdef Z_SOLO
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
#endif
#ifndef local
# define local static
#endif
/* since "static" is used to mean two completely different things in C, we
define "local" for the non-static meaning of "static", for readability
(compile with -Dlocal if your debugger can't find static symbols) */
typedef unsigned char uch;
typedef uch FAR uchf;
typedef unsigned short ush;
typedef ush FAR ushf;
typedef unsigned long ulg;
extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \
return (strm->msg = ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */
/* common constants */
#ifndef DEF_WBITS
# define DEF_WBITS MAX_WBITS
#endif
/* default windowBits for decompression. MAX_WBITS is for compression only */
#if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
/* default memLevel */
#define STORED_BLOCK 0
#define STATIC_TREES 1
#define DYN_TREES 2
/* The three kinds of block type */
#define MIN_MATCH 3
#define MAX_MATCH 258
/* The minimum and maximum match lengths */
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
/* target dependencies */
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00
# ifndef Z_SOLO
# if defined(__TURBOC__) || defined(__BORLANDC__)
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
/* Allow compilation with ANSI keywords only enabled */
void _Cdecl farfree( void *block );
void *_Cdecl farmalloc( unsigned long nbytes );
# else
# include <alloc.h>
# endif
# else /* MSC or DJGPP */
# include <malloc.h>
# endif
# endif
#endif
#ifdef AMIGA
# define OS_CODE 1
#endif
#if defined(VAXC) || defined(VMS)
# define OS_CODE 2
# define F_OPEN(name, mode) \
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif
#ifdef __370__
# if __TARGET_LIB__ < 0x20000000
# define OS_CODE 4
# elif __TARGET_LIB__ < 0x40000000
# define OS_CODE 11
# else
# define OS_CODE 8
# endif
#endif
#if defined(ATARI) || defined(atarist)
# define OS_CODE 5
#endif
#ifdef OS2
# define OS_CODE 6
# if defined(M_I86) && !defined(Z_SOLO)
# include <malloc.h>
# endif
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 7
# ifndef Z_SOLO
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
# include <unix.h> /* for fdopen */
# else
# ifndef fdopen
# define fdopen(fd,mode) NULL /* No fdopen() */
# endif
# endif
# endif
#endif
#ifdef __acorn
# define OS_CODE 13
#endif
#if defined(WIN32) && !defined(__CYGWIN__)
# define OS_CODE 10
#endif
#ifdef _BEOS_
# define OS_CODE 16
#endif
#ifdef __TOS_OS400__
# define OS_CODE 18
#endif
#ifdef __APPLE__
# define OS_CODE 19
#endif
#if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
# if defined(_WIN32_WCE)
# define fdopen(fd,mode) NULL /* No fdopen() */
# ifndef _PTRDIFF_T_DEFINED
typedef int ptrdiff_t;
# define _PTRDIFF_T_DEFINED
# endif
# else
# define fdopen(fd,type) _fdopen(fd,type)
# endif
#endif
#if defined(__BORLANDC__) && !defined(MSDOS)
#pragma warn -8004
#pragma warn -8008
#pragma warn -8066
#endif
/* provide prototypes for these when building zlib without LFS */
#if !defined(_WIN32) && \
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
#endif
/* common defaults */
#ifndef OS_CODE
# define OS_CODE 3 /* assume Unix */
#endif
#ifndef F_OPEN
# define F_OPEN(name, mode) fopen((name), (mode))
#endif
/* functions */
#if defined(pyr) || defined(Z_SOLO)
# define NO_MEMCPY
#endif
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
/* Use our own functions for small and medium model with MSC <= 5.0.
* You may have to use the same strategy for Borland C (untested).
* The __SC__ check is for Symantec.
*/
# define NO_MEMCPY
#endif
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
# define HAVE_MEMCPY
#endif
#ifdef HAVE_MEMCPY
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
# define zmemcpy _fmemcpy
# define zmemcmp _fmemcmp
# define zmemzero(dest, len) _fmemset(dest, 0, len)
# else
# define zmemcpy memcpy
# define zmemcmp memcmp
# define zmemzero(dest, len) memset(dest, 0, len)
# endif
#else
void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
#endif
/* Diagnostic functions */
#ifdef ZLIB_DEBUG
# include <stdio.h>
extern int ZLIB_INTERNAL z_verbose;
extern void ZLIB_INTERNAL z_error OF((char *m));
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
#ifndef Z_SOLO
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
unsigned size));
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
#endif
#define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size))
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
/* Reverse the bytes in a 32-bit value */
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
#endif /* ZUTIL_H */

49
src/Compressor.cpp Normal file
View File

@ -0,0 +1,49 @@
///
/// Created by Anonymous275 on 7/15/2020
///
#include "Zlib/zlib.h"
#include <iostream>
#define Biggest 30000
std::string Comp(std::string Data){
char*C = new char[Biggest];
memset(C, 0, Biggest);
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)Data.length();
defstream.next_in = (Bytef *)&Data[0];
defstream.avail_out = Biggest;
defstream.next_out = reinterpret_cast<Bytef *>(C);
deflateInit(&defstream, Z_BEST_COMPRESSION);
deflate(&defstream, Z_SYNC_FLUSH);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);
int TO = defstream.total_out;
std::string Ret(TO,0);
memcpy_s(&Ret[0],TO,C,TO);
delete [] C;
return Ret;
}
std::string DeComp(std::string Compressed){
char*C = new char[Biggest];
memset(C, 0, Biggest);
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = Biggest;
infstream.next_in = (Bytef *)(&Compressed[0]);
infstream.avail_out = Biggest;
infstream.next_out = (Bytef *)(C);
inflateInit(&infstream);
inflate(&infstream, Z_SYNC_FLUSH);
inflate(&infstream, Z_FINISH);
inflateEnd(&infstream);
int TO = infstream.total_out;
std::string Ret(TO,0);
memcpy_s(&Ret[0],TO,C,TO);
delete [] C;
return Ret;
}

113
src/Enc.cpp Normal file
View File

@ -0,0 +1,113 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "Security/Enc.h"
#include "Settings.h"
#include <windows.h>
#include "Logger.h"
#include <sstream>
#include <thread>
#include <random>
int Rand(){
std::random_device r;
std::default_random_engine e1(r());
std::uniform_int_distribution<int> uniform_dist(1, 5000);
return uniform_dist(e1);
}
int log_power(int n,unsigned int p, int mod){
int result = 1;
for (; p; p >>= 1u){
if (p & 1u)result = int((1LL * result * n) % mod);
n = int((1LL * n * n) % mod);
}
return result;
}
bool rabin_miller(int n){
bool ok = true;
for (int i = 1; i <= 5 && ok; i++) {
int a = Rand() + 1;
int result = log_power(a, n - 1, n);
ok &= (result == 1);
}
return ok;
}
int generate_prime(){
int generated = Rand();
while (!rabin_miller(generated))generated = Rand();
return generated;
}
int gcd(int a, int b){
while (b){
int r = a % b;
a = b;
b = r;
}
return a;
}
int generate_coprime(int n){
int generated = Rand();
while (gcd(n, generated) != 1)generated = Rand();
return generated;
}
std::pair<int, int> euclid_extended(int a, int b) {
if(!b)return {1, 0};
auto result = euclid_extended(b, a % b);
return {result.second, result.first - (a / b) * result.second};
}
int modular_inverse(int n, int mod){
int inverse = euclid_extended(n, mod).first;
while(inverse < 0)inverse += mod;
return inverse;
}
RSA* GenKey(){
int p, q;
p = generate_prime();
q = generate_prime();
int n = p * q;
int phi = (p -1) * (q - 1);
int e = generate_coprime(phi);
int d = modular_inverse(e, phi);
return new RSA{n,e,d};
}
int Enc(int value,int e,int n){
return log_power(value, e, n);
}
int Dec(int value,int d,int n){
return log_power(value, d, n);
}
int Handle(EXCEPTION_POINTERS *ep,char* Origin){
std::stringstream R;
R << Sec("Code : ") << std::hex
<< ep->ExceptionRecord->ExceptionCode
<< std::dec << Sec(" Origin : ") << Origin;
except(R.str());
return 1;
}
std::string RSA_E(const std::string& Data, RSA*k){
std::stringstream stream;
for(const char&c : Data){
stream << std::hex << Enc(uint8_t(c),k->e,k->n) << "g";
}
return stream.str();
}
std::string RSA_D(const std::string& Data, RSA*k){
std::stringstream ss(Data);
std::string token,ret;
while (std::getline(ss, token, 'g')) {
if(token.find_first_not_of(Sec("0123456789abcdef")) != std::string::npos)return "";
int c = std::stoi(token, nullptr, 16);
ret += char(Dec(c,k->d,k->n));
}
return ret;
}

149
src/Init/Config.cpp Normal file
View File

@ -0,0 +1,149 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "Security/Enc.h"
#include "Logger.h"
#include <fstream>
#include <string>
#include <thread>
std::string ServerName;
std::string ServerDesc;
std::string Resource;
std::string MapName;
std::string Key;
int MaxPlayers;
bool Private;
int MaxCars;
bool Debug;
int Port;
void SetValues(const std::string& Line, int Index) {
int state = 0;
std::string Data;
bool Switch = false;
if (Index > 5)Switch = true;
for (char c : Line) {
if (Switch){
if (c == '\"')state++;
if (state > 0 && state < 2)Data += c;
}else{
if (c == ' ')state++;
if (state > 1)Data += c;
}
}
Data = Data.substr(1);
std::string::size_type sz;
bool Boolean = std::string(Data).find("true") != -1;//searches for "true"
switch (Index) {
case 1 :
Debug = Boolean;//checks and sets the Debug Value
break;
case 2 :
Private = Boolean;//checks and sets the Private Value
break;
case 3 :
Port = std::stoi(Data, &sz);//sets the Port
break;
case 4 :
MaxCars = std::stoi(Data, &sz);//sets the Max Car amount
break;
case 5 :
MaxPlayers = std::stoi(Data, &sz); //sets the Max Amount of player
break;
case 6 :
MapName = Data; //Map
break;
case 7 :
ServerName = Data; //Name
break;
case 8 :
ServerDesc = Data; //desc
break;
case 9 :
Resource = Data; //File name
break;
case 10 :
Key = Data; //File name
default:
break;
}
}
std::string RemoveComments(const std::string& Line){
std::string Return;
for(char c : Line) {
if(c == '#')break;
Return += c;
}
return Return;
}
void LoadConfig(std::ifstream& IFS){
std::string line;
int index = 1;
while (getline(IFS, line)) {
index++;
}
if(index-1 < 11){
error(Sec("Outdated/Incorrect config please remove it server will close in 5 secs"));
std::this_thread::sleep_for(std::chrono::seconds(3));
exit(0);
}
IFS.close();
IFS.open(Sec("Server.cfg"));
info(Sec("Config found updating values"));
index = 1;
while (getline(IFS, line)) {
if(line.rfind('#', 0) != 0 && line.rfind(' ', 0) != 0){ //Checks if it starts as Comment
std::string CleanLine = RemoveComments(line); //Cleans it from the Comments
SetValues(CleanLine,index); //sets the values
index++;
}
}
}
void GenerateConfig(){
std::ofstream FileStream;
FileStream.open (Sec("Server.cfg"));
FileStream << Sec("# This is the BeamMP Server Configuration File v0.60\n"
"Debug = false # true or false to enable debug console output\n"
"Private = false # Private?\n"
"Port = 30814 # Port to run the server on UDP and TCP\n"
"Cars = 1 # Max cars for every player\n"
"MaxPlayers = 10 # Maximum Amount of Clients\n"
"Map = \"/levels/gridmap/info.json\" # Default Map\n"
"Name = \"BeamMP New Server\" # Server Name\n"
"Desc = \"BeamMP Default Description\" # Server Description\n"
"use = \"Resources\" # Resource file name\n"
"AuthKey = \"\" # Auth Key");
FileStream.close();
}
void Default(){
info(Sec("Config not found generating default"));
GenerateConfig();
warn(Sec("You are required to input the AuthKey"));
std::this_thread::sleep_for(std::chrono::seconds(3));
exit(0);
}
void DebugData(){
debug(std::string(Sec("Debug : ")) + (Debug?"true":"false"));
debug(std::string(Sec("Private : ")) + (Private?"true":"false"));
debug(Sec("Port : ") + std::to_string(Port));
debug(Sec("Max Cars : ") + std::to_string(MaxCars));
debug(Sec("MaxPlayers : ") + std::to_string(MaxPlayers));
debug(Sec("MapName : ") + MapName);
debug(Sec("ServerName : ") + ServerName);
debug(Sec("ServerDesc : ") + ServerDesc);
debug(Sec("File : ") + Resource);
debug(Sec("Key length: ") + std::to_string(Key.length()));
}
void InitConfig(){
std::ifstream IFS;
IFS.open(Sec("Server.cfg"));
if(IFS.good())LoadConfig(IFS);
else Default();
if(IFS.is_open())IFS.close();
if(Key.empty()){
error(Sec("No AuthKey was found"));
std::this_thread::sleep_for(std::chrono::seconds(3));
exit(0);
}
if(Debug)DebugData();
}

59
src/Init/Heartbeat.cpp Normal file
View File

@ -0,0 +1,59 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "Security/Enc.h"
#include "Curl/Http.h"
#include "Client.hpp"
#include "Settings.h"
#include "Logger.h"
#include <thread>
#include <chrono>
std::string GetPlayers(){
std::string Return;
for(Client* c : CI->Clients){
if(c != nullptr){
Return += c->GetName() + ";";
}
}
return Return;
}
std::string GenerateCall(){
std::string State = Private ? Sec("true") : Sec("false");
std::string ret = Sec("uuid=");
ret += Key+Sec("&players=")+std::to_string(CI->Size())+Sec("&maxplayers=")+std::to_string(MaxPlayers)+Sec("&port=")
+ std::to_string(Port) + Sec("&map=") + MapName + Sec("&private=")+State+Sec("&version=")+GetSVer()+
Sec("&clientversion=")+GetCVer()+Sec("&name=")+ServerName+Sec("&pps=")+StatReport+Sec("&modlist=")+FileList+
Sec("&modstotalsize=")+std::to_string(MaxModSize)+Sec("&modstotal=")+std::to_string(ModsLoaded)
+Sec("&playerslist=")+GetPlayers()+Sec("&desc=")+ServerDesc;
return ret;
}
void Heartbeat(){
std::string R,T;
while(true){
R = GenerateCall();
if(!CustomIP.empty())R+=Sec("&ip=")+CustomIP;
//https://beamng-mp.com/heartbeatv2
std::string link = Sec("https://beamng-mp.com/heartbeatv2");
T = PostHTTP(link,R);
if(T.find_first_not_of(Sec("20")) != std::string::npos){
//Backend system refused server startup!
std::this_thread::sleep_for(std::chrono::seconds(10));
T = PostHTTP(link,R);
if(T.find_first_not_of(Sec("20")) != std::string::npos){
error(Sec("Backend system refused server! Check your AuthKey"));
std::this_thread::sleep_for(std::chrono::seconds(3));
exit(-1);
}
}
//Server Authenticated
if(T.length() == 4)info(Sec("Server authenticated"));
R.clear();
T.clear();
std::this_thread::sleep_for(std::chrono::seconds(3));
}
}
void HBInit(){
std::thread HB(Heartbeat);
HB.detach();
}

View File

@ -1,29 +1,22 @@
///
/// Created by Anonymous275 on 4/11/2020
/// Created by Anonymous275 on 7/28/2020
///
#include <algorithm>
#include "Security/Enc.h"
#include <filesystem>
namespace fs = std::filesystem;
std::string FileList;
#include "Settings.h"
#include <algorithm>
#include "Logger.h"
namespace fs = std::experimental::filesystem;
uint64_t MaxModSize = 0;
std::string FileSizes;
std::string FileList;
int ModsLoaded = 0;
long MaxModSize = 0;
void LuaMain(std::string Path);
void HandleResources(std::string path){
struct stat info{};
if(stat(path.c_str(), &info) != 0){
fs::create_directory(path);
}
LuaMain(path);
path += "/Client";
if(stat(path.c_str(), &info) != 0) {
fs::create_directory(path);
}
for (const auto & entry : fs::directory_iterator(path)){
int pos = entry.path().string().find(".zip");
void InitRes(){
std::string Path = Resource + Sec("/Client");
if(!fs::exists(Path))fs::create_directory(Path);
for (const auto & entry : fs::directory_iterator(Path)){
auto pos = entry.path().string().find(Sec(".zip"));
if(pos != std::string::npos){
if(entry.path().string().length() - pos == 4){
FileList += entry.path().string() + ";";
@ -34,4 +27,7 @@ void HandleResources(std::string path){
}
}
std::replace(FileList.begin(),FileList.end(),'\\','/');
if(ModsLoaded){
info(Sec("Loaded ")+std::to_string(ModsLoaded)+Sec(" Mods"));
}
}

32
src/Init/Startup.cpp Normal file
View File

@ -0,0 +1,32 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "Security/Enc.h"
#include "Client.hpp"
#include "Logger.h"
#include <string>
std::string CustomIP;
std::string GetSVer(){
return Sec("0.60");
}
std::string GetCVer(){
return Sec("1.60");
}
void Args(int argc, char* argv[]){
info(Sec("BeamMP Server Running version ") + GetSVer());
if(argc > 1){
CustomIP = argv[1];
size_t n = std::count(CustomIP.begin(), CustomIP.end(), '.');
auto p = CustomIP.find_first_not_of(Sec(".0123456789"));
if(p != std::string::npos || n != 3 || CustomIP.substr(0,3) == Sec("127")){
CustomIP.clear();
warn(Sec("IP Specified is invalid! Ignoring"));
}else info(Sec("Server started with custom IP"));
}
}
void InitServer(int argc, char* argv[]){
InitLog();
Args(argc,argv);
CI = new ClientInterface;
}

View File

@ -2,9 +2,12 @@
/// Created by Anonymous275 on 5/20/2020
///
#include "LuaSystem.hpp"
#include "../logger.h"
#include "Lua/LuaSystem.hpp"
#include "Security/Enc.h"
#include "Settings.h"
#include "Logger.h"
#include <thread>
std::set<Lua*> PluginEngine;
bool NewFile(const std::string&Path){
for(Lua*Script : PluginEngine){
@ -14,9 +17,9 @@ bool NewFile(const std::string&Path){
}
void RegisterFiles(const std::string& Path,bool HotSwap){
std::string Name = Path.substr(Path.find_last_of('\\')+1);
if(!HotSwap)info("Loading plugin : " + Name);
if(!HotSwap)info(Sec("Loading plugin : ") + Name);
for (const auto &entry : fs::directory_iterator(Path)){
int pos = entry.path().string().find(".lua");
auto pos = entry.path().string().find(Sec(".lua"));
if (pos != std::string::npos && entry.path().string().length() - pos == 4) {
if(!HotSwap || NewFile(entry.path().string())){
Lua *Script = new Lua();
@ -25,7 +28,7 @@ void RegisterFiles(const std::string& Path,bool HotSwap){
Script->SetPluginName(Name);
Script->SetLastWrite(fs::last_write_time(Script->GetFileName()));
Script->Init();
if(HotSwap)info("[HOTSWAP] Added : " +
if(HotSwap)info(Sec("[HOTSWAP] Added : ") +
Script->GetFileName().substr(Script->GetFileName().find('\\')));
}
}
@ -33,7 +36,7 @@ void RegisterFiles(const std::string& Path,bool HotSwap){
}
void FolderList(const std::string& Path,bool HotSwap){
for (const auto &entry : fs::directory_iterator(Path)) {
int pos = entry.path().filename().string().find('.');
auto pos = entry.path().filename().string().find('.');
if (pos == std::string::npos) {
RegisterFiles(entry.path().string(),HotSwap);
}
@ -44,13 +47,15 @@ void FolderList(const std::string& Path,bool HotSwap){
for(Lua*Script : PluginEngine){
struct stat Info{};
if(stat(Script->GetFileName().c_str(), &Info) != 0){
Script->StopThread = true;
PluginEngine.erase(Script);
info("[HOTSWAP] Removed : "+
info(Sec("[HOTSWAP] Removed : ")+
Script->GetFileName().substr(Script->GetFileName().find('\\')));
break;
}
if(Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())){
info("[HOTSWAP] Updated : "+
Script->StopThread = true;
info(Sec("[HOTSWAP] Updated : ")+
Script->GetFileName().substr(Script->GetFileName().find('\\')));
Script->SetLastWrite(fs::last_write_time(Script->GetFileName()));
Script->Reload();
@ -61,16 +66,16 @@ void FolderList(const std::string& Path,bool HotSwap){
}
}
void LuaMain(std::string Path){
Path += "/Server";
struct stat Info{};
if(stat( Path.c_str(), &Info) != 0){
void InitLua(){
if(!fs::exists(Resource)){
fs::create_directory(Resource);
}
std::string Path = Resource + Sec("/Server");
if(!fs::exists(Path)){
fs::create_directory(Path);
}
FolderList(Path,false);
std::thread t1(HotSwaps,Path);
t1.detach();
info("Lua system online");
info(Sec("Lua system online"));
}

View File

@ -2,15 +2,18 @@
/// Created by Anonymous275 on 5/19/2020
///
#include "../Network 2.0/Client.hpp"
#include "LuaSystem.hpp"
#include "../logger.h"
#include "Lua/LuaSystem.hpp"
#include "Security/Enc.h"
#include "Client.hpp"
#include "Network.h"
#include "Logger.h"
#include <iostream>
#include <future>
LuaArg* CreateArg(lua_State *L,int T){
LuaArg* temp = new LuaArg;
for(int C = 2;C <= T;C++){
LuaArg* CreateArg(lua_State *L,int T,int S){
if(S > T)return nullptr;
auto* temp = new LuaArg;
for(int C = S;C <= T;C++){
if(lua_isstring(L,C)){
temp->args.emplace_back(std::string(lua_tostring(L,C)));
}else if(lua_isinteger(L,C)){
@ -23,31 +26,6 @@ LuaArg* CreateArg(lua_State *L,int T){
}
return temp;
}
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg){
int R = 0;
for(Lua*Script : PluginEngine){
if(Script->IsRegistered(Event)){
if(local){
if (Script->GetPluginName() == Caller->GetPluginName()){
R += Script->CallFunction(Script->GetRegistered(Event),arg);
}
}else R += Script->CallFunction(Script->GetRegistered(Event), arg);
}
}
return R;
}
bool CheckLua(lua_State *L, int r)
{
if (r != LUA_OK)
{
std::string errormsg = lua_tostring(L, -1);
std::cout << errormsg << std::endl;
return false;
}
return true;
}
Lua* GetScript(lua_State *L){
for(Lua*Script : PluginEngine){
if (Script->GetState() == L)return Script;
@ -55,121 +33,199 @@ Lua* GetScript(lua_State *L){
return nullptr;
}
void SendError(lua_State *L,const std::string&msg){
Lua* Script = GetScript(L);
error(Script->GetFileName() + " | Incorrect Call of " +msg);
Lua* S = GetScript(L);
std::string a = S->GetFileName().substr(S->GetFileName().find('\\'));
warn(a + Sec(" | Incorrect Call of ") +msg);
}
int lua_RegisterEvent(lua_State *L)
{
int Trigger(Lua*lua,const std::string& R, LuaArg*arg){
std::packaged_task<int()> task([lua,R,arg]{return CallFunction(lua,R,arg);});
std::future<int> f1 = task.get_future();
std::thread t(std::move(task));
t.detach();
auto status = f1.wait_for(std::chrono::seconds(3));
if(status != std::future_status::timeout)return f1.get();
SendError(lua->GetState(),R + " took too long to respond");
return 0;
}
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg){
int R = 0;
for(Lua*Script : PluginEngine){
if(Script->IsRegistered(Event)){
if(local){
if (Script->GetPluginName() == Caller->GetPluginName()){
R += Trigger(Script,Script->GetRegistered(Event),arg);
}
}else R += Trigger(Script,Script->GetRegistered(Event), arg);
}
}
if(arg != nullptr){
delete arg;
arg = nullptr;
}
return R;
}
bool CheckLua(lua_State *L, int r){
if (r != LUA_OK){
std::string msg = lua_tostring(L, -1);
Lua * S = GetScript(L);
std::string a = S->GetFileName().substr(S->GetFileName().find('\\'));
warn(a + " | at line " + msg.substr(msg.find(':')+1));
return false;
}
return true;
}
int lua_RegisterEvent(lua_State *L){
int Args = lua_gettop(L);
Lua* Script = GetScript(L);
if(Args == 2 && lua_isstring(L,1) && lua_isstring(L,2)){
Script->RegisterEvent(lua_tostring(L,1),lua_tostring(L,2));
}else SendError(L,"RegisterEvent invalid argument count expected 2 got " + std::to_string(Args));
}else SendError(L,Sec("RegisterEvent invalid argument count expected 2 got ") + std::to_string(Args));
return 0;
}
int lua_TriggerEventL(lua_State *L)
{
int lua_TriggerEventL(lua_State *L){
int Args = lua_gettop(L);
Lua* Script = GetScript(L);
if(Args > 0){
if(lua_isstring(L,1)) {
TriggerLuaEvent(lua_tostring(L, 1), true, Script, CreateArg(L,Args));
if(lua_isstring(L,1)){
TriggerLuaEvent(lua_tostring(L, 1), true, Script, CreateArg(L,Args,2));
}else SendError(L,Sec("TriggerLocalEvent wrong argument [1] need string"));
}else{
SendError(L,"TriggerLocalEvent wrong argument [1] need string");
}
}else{
SendError(L,"TriggerLocalEvent not enough arguments expected 1 got 0");
SendError(L,Sec("TriggerLocalEvent not enough arguments expected 1 got 0"));
}
return 0;
}
int lua_TriggerEventG(lua_State *L)
{
int lua_TriggerEventG(lua_State *L){
int Args = lua_gettop(L);
Lua* Script = GetScript(L);
if(Args > 0){
if(lua_isstring(L,1)) {
TriggerLuaEvent(lua_tostring(L, 1), false, Script, CreateArg(L,Args));
}else SendError(L,"TriggerGlobalEvent wrong argument [1] need string");
}else{
SendError(L,"TriggerGlobalEvent not enough arguments");
}
TriggerLuaEvent(lua_tostring(L, 1), false, Script, CreateArg(L,Args,2));
}else SendError(L,Sec("TriggerGlobalEvent wrong argument [1] need string"));
}else SendError(L,Sec("TriggerGlobalEvent not enough arguments"));
return 0;
}
void CallAsync(Lua* lua,const std::string& FuncName,LuaArg* args){
char* ThreadOrigin(Lua*lua){
std::string T = "Thread in " + lua->GetFileName().substr(lua->GetFileName().find('\\'));
char* Data = new char[T.size()];
ZeroMemory(Data,T.size());
memcpy_s(Data,T.size(),T.c_str(),T.size());
return Data;
}
void Lock(Lua* lua,bool thread){
bool Lock;
do{
if(thread){
Lock = lua->isExecuting;
}else Lock = lua->isThreadExecuting;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}while(Lock);
}
void ExecuteAsync(Lua* lua,const std::string& FuncName){
Lock(lua,true);
lua->isThreadExecuting = true;
lua_State* luaState = lua->GetState();
lua_getglobal(luaState, FuncName.c_str());
if(lua_isfunction(luaState, -1)) {
char* Origin = ThreadOrigin(lua);
__try{
int R = lua_pcall(luaState, 0, 0, 0);
CheckLua(luaState, R);
}__except(Handle(GetExceptionInformation(),Origin)){}
delete [] Origin;
}
lua->isThreadExecuting = false;
}
void CallAsync(Lua* lua,const std::string& Func,int U){
if(lua->HasThread){
SendError(lua->GetState(),"CreateThread there is a thread already running");
SendError(lua->GetState(),Sec("CreateThread : There is already a thread running!"));
return;
}
lua->StopThread = false;
lua->HasThread = true;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
lua->CallFunction(FuncName,args);
int D = 1000 / U;
while(!lua->StopThread){
ExecuteAsync(lua,Func);
std::this_thread::sleep_for(std::chrono::milliseconds(D));
}
lua->HasThread = false;
}
int lua_StopThread(lua_State *L){
GetScript(L)->StopThread = true;
return 0;
}
int lua_CreateThread(lua_State *L){
int Args = lua_gettop(L);
if(Args > 0){
if(Args > 1){
if(lua_isstring(L,1)) {
std::string STR = lua_tostring(L,1);
std::thread t1(CallAsync,GetScript(L),STR,CreateArg(L,Args));
if(lua_isinteger(L,2) || lua_isnumber(L,2)){
int U = int(lua_tointeger(L,2));
if(U > 0 && U < 501){
std::thread t1(CallAsync,GetScript(L),STR,U);
t1.detach();
}else SendError(L,"CreateThread wrong argument [1] need string");
}else SendError(L,"CreateThread not enough arguments");
}else SendError(L,Sec("CreateThread wrong argument [2] number must be between 1 and 500"));
}else SendError(L,Sec("CreateThread wrong argument [2] need number"));
}else SendError(L,Sec("CreateThread wrong argument [1] need string"));
}else SendError(L,Sec("CreateThread not enough arguments"));
return 0;
}
int lua_Sleep(lua_State *L){
if(lua_isnumber(L,1)){
int t = lua_tonumber(L, 1);
int t = int(lua_tonumber(L, 1));
std::this_thread::sleep_for(std::chrono::milliseconds(t));
}else{
SendError(L,"Sleep not enough arguments");
SendError(L,Sec("Sleep not enough arguments"));
return 0;
}
return 1;
}
Client* GetClient(int ID){
for(Client*c:Clients) {
if(c->GetID() == ID)return c;
for(Client*c : CI->Clients) {
if(c != nullptr && c->GetID() == ID)return c;
}
return nullptr;
}
int lua_isConnected(lua_State *L)
{
int lua_isConnected(lua_State *L){
if(lua_isnumber(L,1)){
int ID = lua_tonumber(L, 1);
int ID = int(lua_tonumber(L, 1));
Client*c = GetClient(ID);
if(c != nullptr)lua_pushboolean(L, c->isConnected());
if(c != nullptr)lua_pushboolean(L, c->isConnected);
else return 0;
}else{
SendError(L,"CreateThread not enough arguments");
SendError(L,Sec("isConnected not enough arguments"));
return 0;
}
return 1;
}
int lua_GetPlayerName(lua_State *L){
if(lua_isnumber(L,1)){
int ID = lua_tonumber(L, 1);
int ID = int(lua_tonumber(L, 1));
Client*c = GetClient(ID);
if(c != nullptr)lua_pushstring(L, c->GetName().c_str());
else return 0;
}else{
SendError(L,"CreateThread not enough arguments");
SendError(L,Sec("GetPlayerName not enough arguments"));
return 0;
}
return 1;
}
int lua_GetPlayerCount(lua_State *L){
lua_pushinteger(L, Clients.size());
lua_pushinteger(L, CI->Size());
return 1;
}
int lua_GetDID(lua_State *L){
if(lua_isnumber(L,1)){
int ID = lua_tonumber(L, 1);
int ID = int(lua_tonumber(L, 1));
Client*c = GetClient(ID);
if(c != nullptr)lua_pushstring(L, c->GetDID().c_str());
else return 0;
}else{
SendError(L,"GetDID not enough arguments");
SendError(L,Sec("GetDID not enough arguments"));
return 0;
}
return 1;
@ -177,85 +233,87 @@ int lua_GetDID(lua_State *L){
int lua_GetAllPlayers(lua_State *L){
lua_newtable(L);
int i = 1;
for (Client *c : Clients) {
for (Client *c : CI->Clients) {
if(c == nullptr)continue;
lua_pushinteger(L, c->GetID());
lua_pushstring(L, c->GetName().c_str());
lua_settable(L,-3);
i++;
}
if(Clients.empty())return 0;
if(CI->Clients.empty())return 0;
return 1;
}
int lua_GetCars(lua_State *L){
if(lua_isnumber(L,1)){
int ID = lua_tonumber(L, 1);
int ID = int(lua_tonumber(L, 1));
Client*c = GetClient(ID);
if(c != nullptr){
int i = 1;
for (const std::pair<int,std::string> &a : c->GetAllCars()) {
lua_pushinteger(L, a.first);
lua_pushstring(L, a.second.substr(3).c_str());
lua_settable(L,-3);
for (VData*v : c->GetAllCars()) {
if(v != nullptr) {
lua_pushinteger(L, v->ID);
lua_pushstring(L, v->Data.substr(3).c_str());
lua_settable(L, -3);
i++;
}
}
if(c->GetAllCars().empty())return 0;
}else return 0;
}else{
SendError(L,"GetPlayerVehicles not enough arguments");
SendError(L,Sec("GetPlayerVehicles not enough arguments"));
return 0;
}
return 1;
}
void Respond(Client*c, const std::string& MSG, bool Rel);
int lua_dropPlayer(lua_State *L){
int Args = lua_gettop(L);
if(lua_isnumber(L,1)){
int ID = lua_tonumber(L, 1);
int ID = int(lua_tonumber(L, 1));
Client*c = GetClient(ID);
if(c == nullptr)return 0;
if(c->GetRole() == "MDEV")return 0;
if(c->GetRole() == Sec("MDEV"))return 0;
std::string Reason;
if(Args > 1 && lua_isstring(L,2)){
Reason = std::string(" Reason : ")+lua_tostring(L,2);
Reason = std::string(Sec(" Reason : "))+lua_tostring(L,2);
}
Respond(c,"C:Server:You have been Kicked from the server!" + Reason,true);
Respond(c,"C:Server:You have been Kicked from the server! " + Reason,true);
c->SetStatus(-2);
closesocket(c->GetTCPSock());
}else SendError(L,"DropPlayer not enough arguments");
}else SendError(L,Sec("DropPlayer not enough arguments"));
return 0;
}
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel);
int lua_sendChat(lua_State *L){
if(lua_isinteger(L,1) || lua_isnumber(L,1)){
if(lua_isstring(L,2)){
int ID = lua_tointeger(L,1);
int ID = int(lua_tointeger(L,1));
if(ID == -1){
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2));
SendToAll(nullptr,Packet,true,true);
}else{
Client*c = GetClient(ID);
if(c != nullptr) {
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2));
if(!c->isSynced)return 0;
std::string Packet ="C:Server: " + std::string(lua_tostring(L, 2));
Respond(c, Packet, true);
}else SendError(L,"SendChatMessage invalid argument [1] invalid ID");
}else SendError(L,Sec("SendChatMessage invalid argument [1] invalid ID"));
}
}else SendError(L,"SendChatMessage invalid argument [2] expected string");
}else SendError(L,"SendChatMessage invalid argument [1] expected number");
}else SendError(L,Sec("SendChatMessage invalid argument [2] expected string"));
}else SendError(L,Sec("SendChatMessage invalid argument [1] expected number"));
return 0;
}
int lua_RemoveVehicle(lua_State *L){
int Args = lua_gettop(L);
if(Args != 2){
SendError(L,"RemoveVehicle invalid argument count expected 2 got " + std::to_string(Args));
SendError(L,Sec("RemoveVehicle invalid argument count expected 2 got ") + std::to_string(Args));
return 0;
}
if((lua_isinteger(L,1) || lua_isnumber(L,1)) && (lua_isinteger(L,2) || lua_isnumber(L,2))){
int PID = lua_tointeger(L,1);
int VID = lua_tointeger(L,2);
int PID = int(lua_tointeger(L,1));
int VID = int(lua_tointeger(L,2));
Client *c = GetClient(PID);
if(c == nullptr){
SendError(L,"RemoveVehicle invalid Player ID");
SendError(L,Sec("RemoveVehicle invalid Player ID"));
return 0;
}
if(c->GetRole() == "MDEV")return 0;
@ -264,7 +322,7 @@ int lua_RemoveVehicle(lua_State *L){
SendToAll(nullptr,Destroy,true,true);
c->DeleteCar(VID);
}
}else SendError(L,"RemoveVehicle invalid argument expected number");
}else SendError(L,Sec("RemoveVehicle invalid argument expected number"));
return 0;
}
int lua_HWID(lua_State *L){
@ -285,6 +343,7 @@ void Lua::Init(){
lua_register(luaState,"CreateThread",lua_CreateThread);
lua_register(luaState,"SendChatMessage",lua_sendChat);
lua_register(luaState,"GetPlayers",lua_GetAllPlayers);
lua_register(luaState,"StopThread",lua_StopThread);
lua_register(luaState,"DropPlayer",lua_dropPlayer);
lua_register(luaState,"GetPlayerHWID",lua_HWID);
lua_register(luaState,"Sleep",lua_Sleep);
@ -293,10 +352,9 @@ void Lua::Init(){
void Lua::Reload(){
if(CheckLua(luaState,luaL_dofile(luaState,FileName.c_str()))){
CallFunction("onInit",{});
CallFunction(this,Sec("onInit"),{});
}
}
int Handle(EXCEPTION_POINTERS *ep,char* Origin);
char* Lua::GetOrigin(){
std::string T = GetFileName().substr(GetFileName().find('\\'));
char* Data = new char[T.size()];
@ -304,26 +362,30 @@ char* Lua::GetOrigin(){
memcpy_s(Data,T.size(),T.c_str(),T.size());
return Data;
}
int Lua::CallFunction(const std::string& FuncName,LuaArg* Arg){
int CallFunction(Lua*lua,const std::string& FuncName,LuaArg* Arg){
Lock(lua,false);
lua->isExecuting = true;
lua_State*luaState = lua->GetState();
lua_getglobal(luaState, FuncName.c_str());
if(lua_isfunction(luaState, -1)) {
int Size = 0;
if(Arg != nullptr){
Size = Arg->args.size();
Size = int(Arg->args.size());
Arg->PushArgs(luaState);
}
int R = 0;
char* Origin = GetOrigin();
char* Origin = lua->GetOrigin();
__try{
R = lua_pcall(luaState, Size, 1, 0);
}__except(Handle(GetExceptionInformation(),Origin)){}
delete [] Origin;
if (CheckLua(luaState, R)){
if (lua_isnumber(luaState, -1)) {
return lua_tointeger(luaState, -1);
return int(lua_tointeger(luaState, -1));
}
}
}__except(Handle(GetExceptionInformation(),Origin)){}
delete [] Origin;
}
lua->isExecuting = false;
return 0;
}
void Lua::SetPluginName(const std::string&Name){

View File

@ -1,85 +0,0 @@
///
/// Created by Anonymous275 on 2/4/2020.
///
#include "Client.hpp"
#include "../logger.h"
#include "../Settings.hpp"
#include "../Lua System/LuaSystem.hpp"
void UDPSend(Client*c,const std::string&Data);
void TCPSend(Client*c,const std::string&Data);
int OpenID(){
int ID = 0;
bool found;
do {
found = true;
for (Client *c : Clients) {
if(c->GetID() == ID){
found = false;
ID++;
}
}
}while (!found);
return ID;
}
void SendLarge(Client*c,const std::string&Data);
void Respond(Client*c, const std::string& MSG, bool Rel){
char C = MSG.at(0);
if(Rel){
if(C == 'C' || C == 'O' || C == 'T' || MSG.length() > 1000)SendLarge(c,MSG);
else TCPSend(c,MSG);
}else UDPSend(c,MSG);
}
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
char C = Data.at(0);
for(Client*client : Clients){
if(Self || client != c){
if(!client->isDownloading){
if(Rel){
if(C == 'C' || C == 'O' || C == 'T' || Data.length() > 1000)SendLarge(client,Data);
else TCPSend(client,Data);
}
else UDPSend(client,Data);
}
}
}
}
void UpdatePlayers(){
std::string Packet = "Ss" + std::to_string(Clients.size())+"/"+std::to_string(MaxPlayers) + ":";
for (Client*c : Clients) {
Packet += c->GetName() + ",";
}
Packet = Packet.substr(0,Packet.length()-1);
SendToAll(nullptr, Packet,true,true);
}
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg);
void Destroy(Client*c){
Clients.erase(c);
delete c;
}
void OnDisconnect(Client*c,bool kicked){
std::string Packet;
for(const std::pair<int,std::string>&a : c->GetAllCars()){
Packet = "Od:" + std::to_string(c->GetID()) + "-" + std::to_string(a.first);
SendToAll(c, Packet,false,true);
}
if(kicked)Packet = "L"+c->GetName()+" was kicked!";
Packet = "L"+c->GetName()+" Left the server!";
SendToAll(c, Packet,false,true);
Packet.clear();
TriggerLuaEvent("onPlayerDisconnect",false,nullptr,new LuaArg{{c->GetID()}});
Destroy(c); ///Removes the Client from existence
}
void SyncResources(Client*c);
#include <thread>
void OnConnect(Client*c){
c->SetID(OpenID());
std::cout << "New Client Created! ID : " << c->GetID() << std::endl;
TriggerLuaEvent("onPlayerConnecting",false,nullptr,new LuaArg{{c->GetID()}});
SyncResources(c);
Respond(c,"M"+MapName,true); //Send the Map on connect
info(c->GetName() + " : Connected");
TriggerLuaEvent("onPlayerJoining",false,nullptr,new LuaArg{{c->GetID()}});
}

View File

@ -1,58 +0,0 @@
///
/// Created by Anonymous275 on 5/9/2020
///
///TCP
#include "Client.hpp"
#include <iostream>
#include <thread>
void TCPSend(Client*c,const std::string&Data){
int BytesSent = send(c->GetTCPSock(), Data.c_str(), int(Data.length())+1, 0);
if (BytesSent == 0){
std::cout << "(TCP) Connection closing..." << std::endl;
if(c->GetStatus() > -1)c->SetStatus(-1);
}
else if (BytesSent < 0) {
std::cout << "(TCP) send failed with error: " << WSAGetLastError() << std::endl;
if(c->GetStatus() > -1)c->SetStatus(-1);
closesocket(c->GetTCPSock());
}
}
void GlobalParser(Client*c, const std::string&Packet);
void TCPRcv(Client*c){
char buf[4096];
int len = 4096;
ZeroMemory(buf, len);
int BytesRcv = recv(c->GetTCPSock(), buf, len,0);
if (BytesRcv == 0){
std::cout << "(TCP) Connection closing..." << std::endl;
if(c->GetStatus() > -1)c->SetStatus(-1);
}
else if (BytesRcv < 0) {
std::cout << "(TCP) recv failed with error: " << WSAGetLastError() << std::endl;
if(c->GetStatus() > -1)c->SetStatus(-1);
closesocket(c->GetTCPSock());
}
GlobalParser(c, std::string(buf));
}
void OnConnect(Client*c);
void OnDisconnect(Client*c,bool kicked);
void TCPClient(Client*client){
if(client->GetTCPSock() == -1)return;
std::cout << "Client connected" << std::endl;
OnConnect(client);
while (client->GetStatus() > -1){
TCPRcv(client);
}
//OnDisconnect
OnDisconnect(client, client->GetStatus() == -2);
std::cout << "Client Terminated" << std::endl;
}
void CreateNewThread(Client*client){
std::thread NewClient(TCPClient,client);
NewClient.detach();
}

View File

@ -1,10 +0,0 @@
#include "Client.hpp"
#include <thread>
void TCPServerMain();
void UDPServerMain();
std::set<Client*> Clients;
void NetMain() {
std::thread TCP(TCPServerMain);
TCP.detach();
UDPServerMain();
}

View File

@ -1,57 +0,0 @@
///
/// Created by Anonymous275 on 7/9/2020
///
#include <random>
#include <thread>
#include "Client.hpp"
#include "../logger.h"
#include "../Settings.hpp"
#include <windows.h>
void VehicleParser(Client*c,const std::string& Pckt);
int Handle(EXCEPTION_POINTERS *ep,char* Origin){
Exception(ep->ExceptionRecord->ExceptionCode,Origin);
return 1;
}
int Rand(){
std::random_device r;
std::default_random_engine e1(r());
std::uniform_int_distribution<int> uniform_dist(1, 200);
return uniform_dist(e1);
}
std::string Encrypt(std::string msg){
if(msg.size() < 2)return msg;
int R = (Rand()+Rand())/2,T = R;
for(char&c : msg){
if(R > 30)c = char(int(c) + (R-=3));
else c = char(int(c) - (R+=4));
}
return char(T) + msg;
}
std::string Decrypt(std::string msg){
int R = uint8_t(msg.at(0));
if(msg.size() < 2 || R > 200 || R < 1)return "";
msg = msg.substr(1);
for(char&c : msg){
if(R > 30)c = char(int(c) - (R-=3));
else c = char(int(c) + (R+=4));
}
return msg;
}
[[noreturn]]void DLoop(){
while(true) {
if(IsDebuggerPresent())VehicleParser(nullptr, "");
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
[[noreturn]]void SLoop(){
std::thread D(DLoop);
D.detach();
int A = -1;
while(true) {
std::this_thread::sleep_for(std::chrono::seconds(20));
if (A == Beat)VehicleParser(nullptr, "");
A = Beat;
}
}

View File

@ -1,38 +0,0 @@
///
/// Created by Anonymous275 on 6/18/2020
///
#include "Client.hpp"
#include <iostream>
#include <string>
#include <thread>
std::string StatReport = "-";
int PPS = 0;
[[noreturn]] void Monitor(){
int R,C,V;
while(true){
if(Clients.empty()){
StatReport = "-";
}else{
C = 0;V = 0;
for(Client *c : Clients){
if(c->GetCarCount() > 0){
C++;
V += c->GetCarCount();
}
}
if(C == 0 || PPS == 0){
StatReport = "-";
}else{
R = (PPS/C)/V;
StatReport = std::to_string(R);
}
PPS = 0;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void StatInit(){
std::thread Init(Monitor);
Init.detach();
}

View File

@ -1,168 +0,0 @@
///
/// Created by Anonymous275 on 5/9/2020
///
///TCP
#include "Client.hpp"
#include <iostream>
#include <WS2tcpip.h>
#include "../logger.h"
#include "../Settings.hpp"
#include <thread>
std::string HTTP_REQUEST(const std::string& IP,int port);
std::string HTA(const std::string& hex);
std::string Decrypt(std::string);
struct Sequence{
SOCKET TCPSock;
bool Done = false;
};
void CreateNewThread(Client*client);
void CreateClient(SOCKET TCPSock,const std::string &Name, const std::string &DID,const std::string &Role) {
auto *client = new Client;
client->SetTCPSock(TCPSock);
client->SetName(Name);
client->SetRole(Role);
client->SetDID(DID);
Clients.insert(client);
CreateNewThread(client);
}
std::string TCPRcv(SOCKET TCPSock){
char buf[4096];
int len = 4096;
ZeroMemory(buf, len);
int BytesRcv = recv(TCPSock, buf, len,0);
if (BytesRcv == 0){
return "";
}
else if (BytesRcv < 0) {
closesocket(TCPSock);
return "";
}
return std::string(buf);
}
std::string HTTP(const std::string &DID){
if(!DID.empty()){
std::string a = HTTP_REQUEST("https://beamng-mp.com/entitlement?did="+DID,443);
if(!a.empty()){
int pos = a.find('"');
if(pos != std::string::npos){
return a.substr(pos+1,a.find('"',pos+1)-2);
}else if(a == "[]")return "Member";
}
}
return "";
}
void Check(Sequence* S){
std::this_thread::sleep_for(std::chrono::seconds(5));
if(S != nullptr){
if(!S->Done)closesocket(S->TCPSock);
delete S;
}
}
int Max(){
int M = MaxPlayers;
for(Client*c : Clients){
if(c->GetRole() == "MDEV")M++;
}
return M;
}
void Identification(SOCKET TCPSock){
auto* S = new Sequence;
S->TCPSock = TCPSock;
std::thread Timeout(Check,S);
Timeout.detach();
std::string Name,DID,Role,Res = TCPRcv(TCPSock),Ver = TCPRcv(TCPSock);
S->Done = true;
Ver = Decrypt(Ver);
if(Ver.size() > 3 && Ver.substr(0,2) == "VC"){
Ver = Ver.substr(2);
if(Ver.length() > 4 || Ver != ClientVersion){
closesocket(TCPSock);
return;
}
}else{
closesocket(TCPSock);
return;
}
Res = Decrypt(Res);
if(Res.size() < 3 || Res.substr(0,2) != "NR") {
closesocket(TCPSock);
return;
}
if(Res.find(':') == std::string::npos){
closesocket(TCPSock);
return;
}
Name = Res.substr(2,Res.find(':')-2);
DID = Res.substr(Res.find(':')+1);
Role = HTTP(DID);
if(Role.empty() || Role.find("Error") != std::string::npos){
closesocket(TCPSock);
return;
}
for(Client*c: Clients){
if(c->GetDID() == DID){
closesocket(c->GetTCPSock());
c->SetStatus(-2);
break;
}
}
if(Debug)debug("Name -> " + Name + ", Role -> " + Role + ", ID -> " + DID);
if(Role == "MDEV"){
CreateClient(TCPSock,Name,DID,Role);
return;
}
if(Clients.size() < Max()){
CreateClient(TCPSock,Name,DID,Role);
}else closesocket(TCPSock);
}
void TCPServerMain(){
WSADATA wsaData;
if (WSAStartup(514, &wsaData)) //2.2
{
std::cout << "Can't start Winsock!" << std::endl;
return;
}
SOCKET client, Listener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sockaddr_in addr{};
addr.sin_addr.S_un.S_addr = ADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = htons(Port);
if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
std::cout << "Can't bind socket! " << WSAGetLastError() << std::endl;
return;
}
if(Listener == -1)
{
printf("Invalid socket");
return;
}
if(listen(Listener,SOMAXCONN))
{
std::cout << "listener failed " << GetLastError();
return;
}
info("Vehicle event network online");
do{
client = accept(Listener, nullptr, nullptr);
if(client == -1)
{
std::cout << "invalid client socket" << std::endl;
continue;
}
std::thread ID(Identification,client);
ID.detach();
}while(client);
closesocket(client);
WSACleanup();
}

172
src/Network/Auth.cpp Normal file
View File

@ -0,0 +1,172 @@
///
/// Created by Anonymous275 on 7/31/2020
///
#include "Security/Enc.h"
#include "Curl/Http.h"
#include "Settings.h"
#include "Network.h"
#include "Logger.h"
#include <sstream>
#include <thread>
struct Hold{
SOCKET TCPSock{};
bool Done = false;
};
bool Send(SOCKET TCPSock,std::string Data){
int BytesSent;
BytesSent = send(TCPSock, Data.c_str(), int(Data.size()), 0);
Data.clear();
if (BytesSent <= 0)return false;
return true;
}
std::string Rcv(SOCKET TCPSock){
char buf[6768];
int len = 6768;
ZeroMemory(buf, len);
int BytesRcv = recv(TCPSock, buf, len,0);
if (BytesRcv <= 0)return "";
return std::string(buf);
}
std::string GetRole(const std::string &DID){
if(!DID.empty()){
std::string a = HttpRequest(Sec("https://beamng-mp.com/entitlement?did=")+DID,443);
if(!a.empty()){
auto pos = a.find('"');
if(pos != std::string::npos){
return a.substr(pos+1,a.find('"',pos+1)-2);
}else if(a == "[]")return Sec("Member");
}
}
return "";
}
void Check(Hold* S){
std::this_thread::sleep_for(std::chrono::seconds(5));
if(S != nullptr){
if(!S->Done)closesocket(S->TCPSock);
}
}
int Max(){
int M = MaxPlayers;
for(Client*c : CI->Clients){
if(c != nullptr){
if(c->GetRole() == Sec("MDEV"))M++;
}
}
return M;
}
void CreateClient(SOCKET TCPSock,const std::string &Name, const std::string &DID,const std::string &Role) {
auto *c = new Client;
c->SetTCPSock(TCPSock);
c->SetName(Name);
c->SetRole(Role);
c->SetDID(DID);
CI->AddClient(c);
InitClient(c);
}
std::string GenerateM(RSA*key){
std::stringstream stream;
stream << std::hex << key->n << "g" << key->e << "g" << RSA_E(Sec("IDC"),key);
return stream.str();
}
void Identification(SOCKET TCPSock,Hold*S,RSA*key){
S->TCPSock = TCPSock;
std::thread Timeout(Check,S);
Timeout.detach();
std::string Name,DID,Role;
if(!Send(TCPSock,GenerateM(key))){
closesocket(TCPSock);
return;
}
std::string Res = Rcv(TCPSock);
std::string Ver = Rcv(TCPSock);
S->Done = true;
Ver = RSA_D(Ver,key);
if(Ver.size() > 3 && Ver.substr(0,2) == Sec("VC")){
Ver = Ver.substr(2);
if(Ver.length() > 4 || Ver != GetCVer()){
closesocket(TCPSock);
return;
}
}else{
closesocket(TCPSock);
return;
}
Res = RSA_D(Res,key);
if(Res.size() < 3 || Res.substr(0,2) != Sec("NR")) {
closesocket(TCPSock);
return;
}
if(Res.find(':') == std::string::npos){
closesocket(TCPSock);
return;
}
Name = Res.substr(2,Res.find(':')-2);
DID = Res.substr(Res.find(':')+1);
Role = GetRole(DID);
if(Role.empty() || Role.find(Sec("Error")) != -1){
closesocket(TCPSock);
return;
}
debug(Sec("Name -> ") + Name + Sec(", Role -> ") + Role + Sec(", ID -> ") + DID);
for(Client*c: CI->Clients){
if(c != nullptr){
if(c->GetDID() == DID){
closesocket(c->GetTCPSock());
c->SetStatus(-2);
break;
}
}
}
if(Role == Sec("MDEV") || CI->Size() < Max()){
CreateClient(TCPSock,Name,DID,Role);
}else closesocket(TCPSock);
}
void Identify(SOCKET TCPSock){
auto* S = new Hold;
RSA*key = GenKey();
__try{
Identification(TCPSock,S,key);
}__except(1){}
delete key;
delete S;
}
void TCPServerMain(){
WSADATA wsaData;
if (WSAStartup(514, &wsaData)){
error(Sec("Can't start Winsock!"));
return;
}
SOCKET client, Listener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sockaddr_in addr{};
addr.sin_addr.S_un.S_addr = ADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = htons(Port);
if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR){
error(Sec("Can't bind socket! ") + std::to_string(WSAGetLastError()));
std::this_thread::sleep_for(std::chrono::seconds(5));
exit(-1);
}
if(Listener == -1){
error(Sec("Invalid listening socket"));
return;
}
if(listen(Listener,SOMAXCONN)){
error(Sec("listener failed ")+ std::to_string(GetLastError()));
return;
}
info(Sec("Vehicle event network online"));
do{
client = accept(Listener, nullptr, nullptr);
if(client == -1){
warn(Sec("Got an invalid client socket on connect! Skipping..."));
continue;
}
std::thread ID(Identify,client);
ID.detach();
}while(client);
closesocket(client);
WSACleanup();
}

View File

@ -12,12 +12,6 @@ void Client::SetName(const std::string& name){
void Client::SetDID(const std::string& did){
DID = did;
}
void Client::SetConnected(bool state){
Connected = state;
}
bool Client::isConnected(){
return Connected;
}
std::string Client::GetDID(){
return DID;
}
@ -52,20 +46,31 @@ SOCKET Client::GetTCPSock(){
return TCPSOCK;
}
void Client::DeleteCar(int ident){
for(const std::pair<int,std::string>& a : VehicleData){
if(a.first == ident){
VehicleData.erase(a);
for(VData* v : VehicleData){
if(v != nullptr && v->ID == ident){
VehicleData.erase(v);
delete v;
v = nullptr;
break;
}
}
}
void Client::ClearCars(){
for(VData* v : VehicleData){
if(v != nullptr){
delete v;
v = nullptr;
}
}
VehicleData.clear();
}
int Client::GetOpenCarID(){
int OpenID = 0;
bool found;
do {
found = true;
for (const std::pair<int, std::string> &a : VehicleData) {
if (a.first == OpenID){
for (VData*v : VehicleData) {
if (v != nullptr && v->ID == OpenID){
OpenID++;
found = false;
}
@ -74,31 +79,31 @@ int Client::GetOpenCarID(){
return OpenID;
}
void Client::AddNewCar(int ident,const std::string& Data){
VehicleData.insert(std::make_pair(ident,Data));
VehicleData.insert(new VData{ident,Data});
}
std::set<std::pair<int,std::string>> Client::GetAllCars(){
std::set<VData*> Client::GetAllCars(){
return VehicleData;
}
std::string Client::GetCarData(int ident){
for(const std::pair<int,std::string>& a : VehicleData){
if(a.first == ident){
return a.second;
for(VData*v : VehicleData){
if(v != nullptr && v->ID == ident){
return v->Data;
}
}
DeleteCar(ident);
return "";
}
void Client::SetCarData(int ident,const std::string&Data){
for(const std::pair<int,std::string>& a : VehicleData){
if(a.first == ident){
VehicleData.erase(a);
VehicleData.insert(std::make_pair(ident,Data));
for(VData*v : VehicleData){
if(v != nullptr && v->ID == ident){
v->Data = Data;
return;
}
}
DeleteCar(ident);
}
int Client::GetCarCount(){
return VehicleData.size();
return int(VehicleData.size());
}

View File

@ -1,26 +1,22 @@
///
/// Created by Anonymous275 on 4/2/2020
/// Created by Anonymous275 on 8/1/2020
///
#include <iostream>
#include "Lua/LuaSystem.hpp"
#include "Security/Enc.h"
#include "Client.hpp"
#include "../logger.h"
#include "../Settings.hpp"
#include "../Lua System/LuaSystem.hpp"
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel);
void Respond(Client*c, const std::string& MSG, bool Rel);
void UpdatePlayers();
int TriggerLuaEvent(const std::string& Event,bool local,Lua*Caller,LuaArg* arg);
#include "Settings.h"
#include "Network.h"
#include "Logger.h"
int FC(const std::string& s,const std::string& p,int n) {
std::string::size_type i = s.find(p);
auto i = s.find(p);
int j;
for (j = 1; j < n && i != std::string::npos; ++j)i = s.find(p, i+1);
if (j == n)return(i);
else return(-1);
for (j = 1; j < n && i != std::string::npos; ++j){
i = s.find(p, i+1);
}
if (j == n)return int(i);
else return -1;
}
int Handle(EXCEPTION_POINTERS *ep,char* Origin);
void Apply(Client*c,int VID,const std::string& pckt){
std::string Packet = pckt;
std::string VD = c->GetCarData(VID);
@ -30,12 +26,9 @@ void Apply(Client*c,int VID,const std::string& pckt){
VD.substr(FC(VD, ",\"", 7));
c->SetCarData(VID, Packet);
}
void UpdateCarData(Client*c,int VID,const std::string& Packet){
__try{
Apply(c,VID,Packet);
}__except(Handle(GetExceptionInformation(),(char*)"Car Data Updater")){}
}
void VehicleParser(Client*c,const std::string& Pckt){
if(c == nullptr || Pckt.length() < 4)return;
std::string Packet = Pckt;
char Code = Packet.at(1);
int PID = -1;
@ -45,20 +38,21 @@ void VehicleParser(Client*c,const std::string& Pckt){
case 's':
if(Data.at(0) == '0'){
int CarID = c->GetOpenCarID();
std::cout << c->GetName() << " CarID : " << CarID << std::endl;
debug(c->GetName() + Sec(" created a car with ID ") + std::to_string(CarID));
Packet = "Os:"+c->GetRole()+":"+c->GetName()+":"+std::to_string(c->GetID())+"-"+std::to_string(CarID)+Packet.substr(4);
if(c->GetCarCount() >= MaxCars ||
TriggerLuaEvent("onVehicleSpawn",false,nullptr,
TriggerLuaEvent(Sec("onVehicleSpawn"),false,nullptr,
new LuaArg{{c->GetID(),CarID,Packet.substr(3)}})){
Respond(c,Packet,true);
std::string Destroy = "Od:" + std::to_string(c->GetID())+"-"+std::to_string(CarID);
Respond(c,Destroy,true);
debug(c->GetName() + Sec(" (force : car limit/lua) removed ID ") + std::to_string(CarID));
}else{
c->AddNewCar(CarID,Packet);
SendToAll(nullptr, Packet,true,true);
}
}
break;
return;
case 'c':
pid = Data.substr(0,Data.find('-'));
vid = Data.substr(Data.find('-')+1,Data.find(':',1)-Data.find('-')-1);
@ -67,18 +61,17 @@ void VehicleParser(Client*c,const std::string& Pckt){
VID = stoi(vid);
}
if(PID != -1 && VID != -1 && PID == c->GetID()){
if(!TriggerLuaEvent("onVehicleEdited",false,nullptr,
if(!TriggerLuaEvent(Sec("onVehicleEdited"),false,nullptr,
new LuaArg{{c->GetID(),VID,Packet.substr(3)}})) {
SendToAll(c, Packet, false, true);
UpdateCarData(c,VID,Packet);
Apply(c,VID,Packet);
}else{
std::string Destroy = "Od:" + std::to_string(c->GetID())+"-"+std::to_string(VID);
Respond(c,Destroy,true);
c->DeleteCar(VID);
}
}
break;
return;
case 'd':
pid = Data.substr(0,Data.find('-'));
vid = Data.substr(Data.find('-')+1);
@ -88,82 +81,91 @@ void VehicleParser(Client*c,const std::string& Pckt){
}
if(PID != -1 && VID != -1 && PID == c->GetID()){
SendToAll(nullptr,Packet,true,true);
TriggerLuaEvent("onVehicleDeleted",false,nullptr,
TriggerLuaEvent(Sec("onVehicleDeleted"),false,nullptr,
new LuaArg{{c->GetID(),VID}});
c->DeleteCar(VID);
debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(VID));
}
break;
return;
case 'r':
SendToAll(c,Packet,false,true);
break;
//case 'm':
// break;
return;
default:
break;
return;
}
Data.clear();
Packet.clear();
}
void SyncVehicles(Client*c){
Respond(c,"Sn"+c->GetName(),true);
SendToAll(c,"JWelcome "+c->GetName()+"!",false,true);
TriggerLuaEvent("onPlayerJoin",false,nullptr,new LuaArg{{c->GetID()}});
for (Client*client : Clients) {
void SyncClient(Client*c){
if(c->isSynced)return;
Respond(c,Sec("Sn")+c->GetName(),true);
SendToAll(c,Sec("JWelcome ")+c->GetName()+"!",false,true);
TriggerLuaEvent(Sec("onPlayerJoin"),false,nullptr,new LuaArg{{c->GetID()}});
for (Client*client : CI->Clients) {
if(client != nullptr){
if (client != c) {
for(const std::pair<int,std::string>&a : client->GetAllCars()){
Respond(c,a.second,true);
for (VData *v : client->GetAllCars()) {
Respond(c, v->Data, true);
}
}
}
}
c->isSynced = true;
info(c->GetName() + Sec(" is now synced!"));
}
extern int PPS;
void ParseVeh(Client*c, const std::string&Packet){
__try{
VehicleParser(c,Packet);
}__except(Handle(GetExceptionInformation(),(char*)"Vehicle Handler")){}
}__except(Handle(GetExceptionInformation(),Sec("Vehicle Handler"))){}
}
void GlobalParser(Client*c, const std::string&Packet){
if(Packet.empty())return;
if(Packet.find("TEST")!=std::string::npos)SyncVehicles(c);
void GlobalParser(Client*c, const std::string& Packet){
static int lastRecv = 0;
if(Packet.empty() || c == nullptr)return;
std::string pct;
char Code = Packet.at(0);
//V to Z
if(Code <= 90 && Code >= 86){
PPS++;
SendToAll(c,Packet,false,false);
return;
}
switch (Code) {
case 'P':
Respond(c, "P" + std::to_string(c->GetID()),true);
Respond(c, Sec("P") + std::to_string(c->GetID()),true);
SyncClient(c);
return;
case 'p':
Respond(c,"p",false);
Respond(c,Sec("p"),false);
UpdatePlayers();
return;
case 'O':
if(Packet.length() > 1000) {
std::cout << "Received data from: " << c->GetName() << " Size: " << Packet.length() << std::endl;
debug(Sec("Received data from: ") + c->GetName() + Sec(" Size: ") + std::to_string(Packet.length()));
}
ParseVeh(c,Packet);
return;
case 'J':
SendToAll(c,Packet,false,true);
break;
return;
case 'C':
if(Packet.length() < 4 || Packet.find(':', 3) == -1)break;
pct = "C:" + c->GetName() + Packet.substr(Packet.find(':', 3));
if (TriggerLuaEvent("onChatMessage", false, nullptr,
new LuaArg{{ c->GetID(), c->GetName(), pct.substr(pct.find(':', 3) + 1) }}))break;
if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr,
new LuaArg{{c->GetID(), c->GetName(), pct.substr(pct.find(':', 3) + 1)}}))break;
SendToAll(nullptr, pct, true, true);
pct.clear();
break;
return;
case 'E':
SendToAll(nullptr,Packet,true,true);
break;
return;
default:
break;
return;
}
//V to Z
if(Code <= 90 && Code >= 86){
PPS++;
SendToAll(c,Packet,false,false);
}
if(Debug)debug("Vehicle Data Received from " + c->GetName());
}
void GParser(Client*c, const std::string&Packet){
__try{
GlobalParser(c, Packet);
}__except(Handle(GetExceptionInformation(),Sec("Global Handler"))){}
}

View File

@ -1,18 +1,14 @@
///
/// Created by Anonymous275 on 4/9/2020
///
#define CURL_STATICLIB
#include "curl/curl.h"
#include "Curl/curl.h"
#include <iostream>
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp){
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
std::string HTTP_REQUEST(const std::string& IP,int port){
std::string HttpRequest(const std::string& IP,int port){
CURL *curl;
CURLcode res;
std::string readBuffer;
@ -24,6 +20,7 @@ std::string HTTP_REQUEST(const std::string& IP,int port){
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(res != CURLE_OK)return "-1";
}
return readBuffer;
}
@ -32,7 +29,6 @@ std::string PostHTTP(const std::string& IP,const std::string& Fields){
CURL *curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, IP.c_str());
@ -43,6 +39,7 @@ std::string PostHTTP(const std::string& IP,const std::string& Fields){
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(res != CURLE_OK)return "-1";
}
return readBuffer;
}

View File

@ -0,0 +1,82 @@
///
/// Created by Anonymous275 on 8/1/2020
///
#include "Lua/LuaSystem.hpp"
#include "Security/Enc.h"
#include "Client.hpp"
#include "Settings.h"
#include "Network.h"
#include "Logger.h"
int OpenID(){
int ID = 0;
bool found;
do {
found = true;
for (Client *c : CI->Clients){
if(c != nullptr){
if(c->GetID() == ID){
found = false;
ID++;
}
}
}
}while (!found);
return ID;
}
void Respond(Client*c, const std::string& MSG, bool Rel){
char C = MSG.at(0);
if(Rel){
if(C == 'O' || C == 'T' || MSG.length() > 1000)SendLarge(c,MSG);
else TCPSend(c,MSG);
}else UDPSend(c,MSG);
}
void SendToAll(Client*c, const std::string& Data, bool Self, bool Rel){
char C = Data.at(0);
for(Client*client : CI->Clients){
if(client != nullptr) {
if (Self || client != c) {
if (client->isSynced) {
if (Rel) {
if (C == 'O' || C == 'T' || Data.length() > 1000)SendLarge(client, Data);
else TCPSend(client, Data);
} else UDPSend(client, Data);
}
}
}
}
}
void UpdatePlayers(){
std::string Packet = Sec("Ss") + std::to_string(CI->Size())+"/"+std::to_string(MaxPlayers) + ":";
for (Client*c : CI->Clients) {
if(c != nullptr)Packet += c->GetName() + ",";
}
Packet = Packet.substr(0,Packet.length()-1);
SendToAll(nullptr, Packet,true,true);
}
void OnDisconnect(Client*c,bool kicked){
if(c == nullptr)return;
std::string Packet;
for(VData*v : c->GetAllCars()){
if(v != nullptr) {
Packet = "Od:" + std::to_string(c->GetID()) + "-" + std::to_string(v->ID);
SendToAll(c, Packet, false, true);
}
}
if(kicked)Packet = Sec("L")+c->GetName()+Sec(" was kicked!");
Packet = Sec("L")+c->GetName()+Sec(" Left the server!");
SendToAll(c, Packet,false,true);
Packet.clear();
TriggerLuaEvent(Sec("onPlayerDisconnect"),false,nullptr,new LuaArg{{c->GetID()}});
c->ClearCars();
CI->RemoveClient(c); ///Removes the Client from existence
}
void OnConnect(Client*c){
c->SetID(OpenID());
info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName());
TriggerLuaEvent(Sec("onPlayerConnecting"),false,nullptr,new LuaArg{{c->GetID()}});
SyncResources(c);
if(c->GetStatus() < 0)return;
Respond(c,"M"+MapName,true); //Send the Map on connect
info(c->GetName() + Sec(" : Connected"));
TriggerLuaEvent(Sec("onPlayerJoining"),false,nullptr,new LuaArg{{c->GetID()}});
}

8
src/Network/NetMain.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "Network.h"
#include <thread>
ClientInterface* CI;
void NetMain(){
std::thread TCP(TCPServerMain);
TCP.detach();
UDPServerMain();
}

View File

@ -0,0 +1,43 @@
///
/// Created by Anonymous275 on 6/18/2020
///
#include "Security/Enc.h"
#include "Client.hpp"
#include <iostream>
#include <string>
#include <thread>
std::string StatReport;
int PPS = 0;
void Monitor() {
int R, C = 0, V = 0;
if (CI->Clients.empty()){
StatReport = "-";
return;
}
for (Client *c : CI->Clients) {
if (c != nullptr && c->GetCarCount() > 0) {
C++;
V += c->GetCarCount();
}
}
if (C == 0 || PPS == 0) {
StatReport = "-";
} else {
R = (PPS / C) / V;
StatReport = std::to_string(R);
}
PPS = 0;
}
[[noreturn]]void Stat(){
while(true){
Monitor();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void StatInit(){
StatReport = "-";
std::thread Init(Stat);
Init.detach();
}

View File

@ -1,70 +1,57 @@
///
/// Created by Anonymous275 on 6/10/2020
/// Created by Anonymous275 on 8/1/2020
///
#include <string>
#include "../Settings.hpp"
#include "Security/Enc.h"
#include "Client.hpp"
#include <iostream>
#include "Settings.h"
#include "Logger.h"
#include <fstream>
#include <any>
std::string Encrypt(std::string msg);
void STCPSend(Client*c,std::any Data,size_t Size){
void STCPSend(Client*c,std::string Data){
if(c == nullptr)return;
int BytesSent;
if(std::string(Data.type().name()).find("string") != std::string::npos){
auto data = std::any_cast<std::string>(Data);
BytesSent = send(c->GetTCPSock(), data.c_str(), data.size(), 0);
data.clear();
}else{
char* D = std::any_cast<char*>(Data);
BytesSent = send(c->GetTCPSock(), D, Size, 0);
delete[] D;
}
BytesSent = send(c->GetTCPSock(), Data.c_str(), int(Data.size()), 0);
Data.clear();
if (BytesSent == 0){
std::cout << "(STCPS) Connection closing..." << std::endl;
if(c->GetStatus() > -1)c->SetStatus(-1);
}
else if (BytesSent < 0) {
std::cout << "(STCPS) send failed with error: " << WSAGetLastError() << std::endl;
}else if (BytesSent < 0) {
if(c->GetStatus() > -1)c->SetStatus(-1);
closesocket(c->GetTCPSock());
}
}
void SendFile(Client*c,const std::string&Name){
std::cout << c->GetName() << " requesting : "
<< Name.substr(Name.find_last_of('/')) << std::endl;
info(c->GetName()+Sec(" requesting : ")+Name.substr(Name.find_last_of('/')));
struct stat Info{};
if(stat(Name.c_str(), &Info) != 0){
STCPSend(c,std::string("Cannot Open"),0);
STCPSend(c,Sec("Cannot Open"));
return;
}
std::ifstream f(Name.c_str(), std::ios::binary);
f.seekg(0, std::ios_base::end);
std::streampos fileSize = f.tellg();
size_t Size = fileSize,Sent = 0,Diff;
char* Data;
int Split = 64000;
while(c->GetStatus() > -1 && Sent < Size){
Diff = Size - Sent;
if(Diff > Split){
Data = new char[Split];
std::string Data(Split,0);
f.seekg(Sent, std::ios_base::beg);
f.read(Data, Split);
STCPSend(c,Data,Split);
f.read(&Data[0], Split);
STCPSend(c,Data);
Sent += Split;
}else{
Data = new char[Diff];
std::string Data(Diff,0);
f.seekg(Sent, std::ios_base::beg);
f.read(Data, Diff);
STCPSend(c,Data,Diff);
f.read(&Data[0], Diff);
STCPSend(c,Data);
Sent += Diff;
}
}
f.close();
}
void Parse(Client*c,char*data){
std::string Packet = data;
if(Packet.empty())return;
void Parse(Client*c,const std::string&Packet){
if(c == nullptr || Packet.empty())return;
char Code = Packet.at(0),SubCode = 0;
if(Packet.length() > 1)SubCode = Packet.at(1);
switch (Code) {
@ -73,42 +60,44 @@ void Parse(Client*c,char*data){
return;
case 'S':
if(SubCode == 'R'){
std::cout << "Sending File Info" << std::endl;
debug(Sec("Sending Mod Info"));
std::string ToSend = FileList+FileSizes;
if(ToSend.empty())ToSend = "-";
STCPSend(c,ToSend,0);
STCPSend(c,ToSend);
}
return;
default:
return;
}
}
bool STCPRecv(Client*c){
if(c == nullptr)return false;
char buf[200];
int len = 200;
ZeroMemory(buf, len);
int BytesRcv = recv(c->GetTCPSock(), buf, len,0);
if (BytesRcv == 0){
std::cout << "(STCPR) Connection closing..." << std::endl;
if(c->GetStatus() > -1)c->SetStatus(-1);
closesocket(c->GetTCPSock());
return false;
}
else if (BytesRcv < 0) {
std::cout << "(STCPR) recv failed with error: " << WSAGetLastError() << std::endl;
}else if (BytesRcv < 0) {
if(c->GetStatus() > -1)c->SetStatus(-1);
closesocket(c->GetTCPSock());
return false;
}
if(strcmp(buf,"Done") == 0)return false;
char* Ret = new char[BytesRcv];
memcpy_s(Ret,BytesRcv,buf,BytesRcv);
ZeroMemory(buf, len);
std::string Ret(buf,BytesRcv);
Parse(c,Ret);
delete[] Ret;
return true;
}
void SyncResources(Client*c){
STCPSend(c,Encrypt("WS"),0);
if(c == nullptr)return;
try{
STCPSend(c,Sec("WS"));
while(c->GetStatus() > -1 && STCPRecv(c));
c->isDownloading = false;
}catch (std::exception& e){
except(Sec("Exception! : ") + std::string(e.what()));
c->SetStatus(-1);
}
}

View File

@ -0,0 +1,52 @@
///
/// Created by Anonymous275 on 8/1/2020
///
#include "Security/Enc.h"
#include "Network.h"
#include "Logger.h"
#include <thread>
void TCPSend(Client*c,const std::string&Data){
if(c == nullptr)return;
int BytesSent = send(c->GetTCPSock(), Data.c_str(), int(Data.length())+1, 0);
if (BytesSent == 0){
if(c->GetStatus() > -1)c->SetStatus(-1);
}else if (BytesSent < 0) {
if(c->GetStatus() > -1)c->SetStatus(-1);
closesocket(c->GetTCPSock());
}
}
void TCPRcv(Client*c){
if(c == nullptr)return;
char buf[4096];
int len = 4096;
ZeroMemory(buf, len);
int BytesRcv = recv(c->GetTCPSock(), buf, len,0);
if (BytesRcv == 0){
debug(Sec("(TCP) Connection closing..."));
if(c->GetStatus() > -1)c->SetStatus(-1);
return;
}else if (BytesRcv < 0) {
debug(Sec("(TCP) recv failed with error: ") + std::to_string(WSAGetLastError()));
if(c->GetStatus() > -1)c->SetStatus(-1);
closesocket(c->GetTCPSock());
return;
}
std::string Buf(buf,BytesRcv);
GParser(c, Buf);
}
void TCPClient(Client*c){
if(c->GetTCPSock() == -1){
CI->RemoveClient(c);
return;
}
info(Sec("Client connected"));
OnConnect(c);
while (c->GetStatus() > -1)TCPRcv(c);
info(c->GetName() + Sec(" Connection Terminated"));
OnDisconnect(c, c->GetStatus() == -2);
}
void InitClient(Client*c){
std::thread NewClient(TCPClient,c);
NewClient.detach();
}

View File

@ -2,13 +2,14 @@
/// Created by Anonymous275 on 5/8/2020
///
///UDP
#include "Security/Enc.h"
#include "Compressor.h"
#include "Client.hpp"
#include <iostream>
#include "Settings.h"
#include "Network.h"
#include "Logger.h"
#include <vector>
#include <array>
#include "../logger.h"
#include "../Settings.hpp"
struct PacketData{
int ID;
@ -25,12 +26,20 @@ struct SplitData{
SOCKET UDPSock;
std::set<PacketData*> DataAcks;
std::set<SplitData*> SplitPackets;
void UDPSend(Client*c,const std::string&Data){
if(!c->isConnected())return;
void UDPSend(Client*c,std::string Data){
if(c == nullptr || !c->isConnected || c->GetStatus() < 0)return;
sockaddr_in Addr = c->GetUDPAddr();
int AddrSize = sizeof(c->GetUDPAddr());
int sendOk = sendto(UDPSock, Data.c_str(), int(Data.length()) + 1, 0, (sockaddr*)&Addr, AddrSize);
if (sendOk == SOCKET_ERROR)error("(UDP) Send Error Code : " + std::to_string(WSAGetLastError()) + " Size : " + std::to_string(AddrSize));
if(Data.length() > 400){
std::string CMP(Comp(Data));
Data = "ABG:" + CMP;
}
int sendOk = sendto(UDPSock, Data.c_str(), int(Data.size()), 0, (sockaddr *) &Addr, AddrSize);
if (sendOk == SOCKET_ERROR) {
debug(Sec("(UDP) Send Failed Code : ") + std::to_string(WSAGetLastError()));
if(c->GetStatus() > -1)c->SetStatus(-1);
}
}
void AckID(int ID){
@ -58,7 +67,7 @@ void SendLarge(Client*c,const std::string&Data){
std::string Packet;
if(Data.length() > 1000){
std::string pckt = Data;
int S = 1,Split = ceil(float(pckt.length()) / 1000);
int S = 1,Split = int(ceil(float(pckt.length()) / 1000));
int SID = SplitID();
while(pckt.length() > 1000){
Packet = "SC"+std::to_string(S)+"/"+std::to_string(Split)+":"+std::to_string(ID)+"|"+
@ -79,8 +88,6 @@ void SendLarge(Client*c,const std::string&Data){
UDPSend(c,Packet);
}
}
struct HandledC{
int Pos = 0;
Client *c{};
@ -114,12 +121,12 @@ bool Handled(Client*c,int ID){
}
}
for(HandledC*h : HandledIDs){
if(h->c == nullptr || !h->c->isConnected()){
if(h->c == nullptr || !h->c->isConnected){
HandledIDs.erase(h);
break;
}
}
if(!handle) {
if(!handle){
HandledC *h = GetHandled(c);
ResetIDs(h);
if (h->Pos > 49)h->Pos = 0;
@ -135,13 +142,14 @@ std::string UDPRcvFromClient(sockaddr_in& client){
int clientLength = sizeof(client);
ZeroMemory(&client, clientLength);
ZeroMemory(buf, 10240);
int bytesIn = recvfrom(UDPSock, buf, 10240, 0, (sockaddr*)&client, &clientLength);
if (bytesIn == -1)
{
error("(UDP) Error receiving from Client! Code : " + std::to_string(WSAGetLastError()));
int Rcv = recvfrom(UDPSock, buf, 10240, 0, (sockaddr*)&client, &clientLength);
if (Rcv == -1){
error(Sec("(UDP) Error receiving from Client! Code : ") + std::to_string(WSAGetLastError()));
return "";
}
return std::string(buf);
std::string Ret(Rcv,0);
memcpy_s(&Ret[0],Rcv,buf,Rcv);
return Ret;
}
SplitData*GetSplit(int SplitID){
@ -152,16 +160,17 @@ SplitData*GetSplit(int SplitID){
SplitPackets.insert(SP);
return SP;
}
void GlobalParser(Client*c, const std::string&Packet);
void HandleChunk(Client*c,const std::string&Data){
int pos1 = int(Data.find(':'))+1,pos2 = Data.find(':',pos1),pos3 = Data.find('/');
int pos4 = Data.find('|');
int pos1 = int(Data.find(':'))+1,
pos2 = int(Data.find(':',pos1)),
pos3 = int(Data.find('/')),
pos4 = int(Data.find('|'));
if(pos1 == std::string::npos)return;
int Max = stoi(Data.substr(pos3+1,pos1-pos3-2));
int Current = stoi(Data.substr(2,pos3-2));
int ID = stoi(Data.substr(pos1,pos4-pos1));
int SplitID = stoi(Data.substr(pos4+1,pos2-pos4-1));
std::string ack = "ACK:" + Data.substr(pos1,pos4-pos1);
std::string ack = Sec("TRG:") + Data.substr(pos1,pos4-pos1);
UDPSend(c,ack);
if(Handled(c,ID))return;
SplitData* SData = GetSplit(SplitID);
@ -173,43 +182,46 @@ void HandleChunk(Client*c,const std::string&Data){
for(const std::pair<int,std::string>& a : SData->Fragments){
ToHandle += a.second;
}
GlobalParser(c,ToHandle);
GParser(c,ToHandle);
SplitPackets.erase(SData);
}
}
void UDPParser(Client*c, const std::string&Packet){
if(Packet.substr(0,4) == "ACK:"){
AckID(stoi(Packet.substr(4)));
return;
}else if(Packet.substr(0,3) == "BD:"){
int pos = Packet.find(':',4);
int ID = stoi(Packet.substr(3,pos-3));
std::string pckt = "ACK:" + std::to_string(ID);
UDPSend(c,pckt);
if(!Handled(c,ID)) {
pckt = Packet.substr(pos + 1);
GlobalParser(c, pckt);
void UDPParser(Client*c,std::string Packet){
if(Packet.substr(0,4) == Sec("ABG:")){
Packet = DeComp(Packet.substr(4));
}
if(Packet.substr(0,4) == Sec("TRG:")){
std::string pkt = Packet.substr(4);
if(Packet.find_first_not_of("0123456789") == -1){
AckID(stoi(Packet));
}
return;
}else if(Packet.substr(0,2) == "SC"){
}else if(Packet.substr(0,3) == Sec("BD:")){
auto pos = Packet.find(':',4);
int ID = stoi(Packet.substr(3,pos-3));
std::string pkt = Sec("TRG:") + std::to_string(ID);
UDPSend(c,pkt);
if(!Handled(c,ID)) {
pkt = Packet.substr(pos + 1);
GParser(c, pkt);
}
return;
}else if(Packet.substr(0,2) == Sec("SC")){
HandleChunk(c,Packet);
return;
}
GlobalParser(c,Packet);
GParser(c,Packet);
}
#include <thread>
void StartLoop();
[[noreturn]] void UDPServerMain(){
WSADATA data;
if (WSAStartup(514, &data)) //2.2
{
std::cout << "Can't start Winsock!" << std::endl;
if (WSAStartup(514, &data)){
error(Sec("Can't start Winsock!"));
//return;
}
UDPSock = socket(AF_INET, SOCK_DGRAM, 0);
// Create a server hint structure for the server
sockaddr_in serverAddr{};
serverAddr.sin_addr.S_un.S_addr = ADDR_ANY; //Any Local
@ -217,55 +229,58 @@ void StartLoop();
serverAddr.sin_port = htons(Port); // Convert from little to big endian
// Try and bind the socket to the IP and port
if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
std::cout << "Can't bind socket! " << WSAGetLastError() << std::endl;
if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR){
error(Sec("Can't bind socket!") + std::to_string(WSAGetLastError()));
std::this_thread::sleep_for(std::chrono::seconds(5));
exit(-1);
//return;
}
DataAcks.clear();
StartLoop();
info("Vehicle data network online on port "+std::to_string(Port)+" with a Max of "+std::to_string(MaxPlayers)+" Clients");
while (true)
{
info(Sec("Vehicle data network online on port ")+std::to_string(Port)+Sec(" with a Max of ")+std::to_string(MaxPlayers)+Sec(" Clients"));
while (true){
sockaddr_in client{};
std::string Data = UDPRcvFromClient(client); //Receives any data from Socket
int Pos = Data.find(':');
auto Pos = Data.find(':');
if(Data.empty() || Pos < 0 || Pos > 2)continue;
/*char clientIp[256];
ZeroMemory(clientIp, 256); ///Code to get IP we don't need that yet
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);*/
uint8_t ID = Data.at(0)-1;
for(Client*c : Clients){
if(c->GetID() == ID){
for(Client*c : CI->Clients){
if(c != nullptr && c->GetID() == ID){
c->SetUDPAddr(client);
c->SetConnected(true);
UDPParser(c,Data.substr(2));
c->isConnected = true;
std::thread Parse(UDPParser,c,Data.substr(2));
Parse.detach();
}
}
}
///UDPSendToClient(c->GetUDPAddr(), sizeof(c->GetUDPAddr()), Data);
/*closesocket(UDPSock);
WSACleanup();
return;*/
}
#include <thread>
void LOOP(){
while(UDPSock != -1) {
for (PacketData* p : DataAcks){
if(p != nullptr) {
if (p->Client == nullptr || p->Client->GetTCPSock() == -1) {
DataAcks.erase(p);
break;
}
if(p->Tries < 20){
UDPSend(p->Client,p->Data);
if (p->Tries < 20) {
UDPSend(p->Client, p->Data);
p->Tries++;
}else{
} else {
DataAcks.erase(p);
delete p;
p = nullptr;
break;
}
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}

View File

@ -1,132 +0,0 @@
///
/// Created by Anonymous275 on 1/28/2020
///
#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include "logger.h"
void GenerateConfig();
std::string RemoveComments(const std::string& Line);
void SetValues(const std::string& Line, int Index);
std::string MapName = "/levels/gridmap/info.json";
std::string ServerName = "BeamMP New Server";
std::string ServerDesc = "BeamMP Default Description";
std::string Resource = "Resources";
std::string Key;
bool Private = false;
bool Debug = false;
int MaxPlayers = 10;
int Port = 30814;
int MaxCars = 1;
//Generates or Reads Config
void ParseConfig(){
std::ifstream InFileStream;
InFileStream.open("Server.cfg");
if(InFileStream.good()){ //Checks if Config Exists
std::string line;
int index = 1;
while (getline(InFileStream, line)) {
index++;
}
if(index-1 < 11){
error("Outdated/Incorrect config please remove it server will close in 5 secs");
std::this_thread::sleep_for(std::chrono::seconds(5));
exit(3);
}
InFileStream.close();
InFileStream.open("Server.cfg");
info("Config Found Updating Values");
index = 1;
while (getline(InFileStream, line)) {
if(line.rfind('#', 0) != 0 && line.rfind(' ', 0) != 0){ //Checks if it starts as Comment
std::string CleanLine = RemoveComments(line); //Cleans it from the Comments
SetValues(CleanLine,index); //sets the values
index++;
}
}
}else{
info("Config Not Found Generating A new One");
GenerateConfig();
}
InFileStream.close();
}
void SetValues(const std::string& Line, int Index) {
int state = 0;
std::string Data;
bool Switch = false;
if (Index > 5)Switch = true;
for (char c : Line) {
if (Switch) {
if (c == '\"'){state++;}
if (state > 0 && state < 2) {
Data += c;
}
} else {
if (c == ' ') { state++; }
if (state > 1) {
Data += c;
}
}
}
Data = Data.substr(1);
std::string::size_type sz;
bool Boolean = std::string(Data).find("true") != std::string::npos;//searches for "true"
switch (Index){
case 1 : Debug = Boolean;//checks and sets the Debug Value
break;
case 2 : Private = Boolean;//checks and sets the Private Value
break;
case 3 : Port = std::stoi(Data, &sz);//sets the Port
break;
case 4 : MaxCars = std::stoi(Data, &sz);//sets the Max Car amount
break;
case 5 : MaxPlayers = std::stoi(Data, &sz); //sets the Max Amount of player
break;
case 6 : MapName = Data; //Map
break;
case 7 : ServerName = Data; //Name
break;
case 8 : ServerDesc = Data; //desc
break;
case 9 : Resource = Data; //File name
break;
case 10 : Key = Data; //File name
}
}
//generates default Config
void GenerateConfig(){
std::ofstream FileStream;
FileStream.open ("Server.cfg");
FileStream << "# This is the BeamMP Server Configuration File\n"
"Debug = false # true or false to enable debug console output\n"
"Private = false # Private?\n"
"Port = 30814 # Port to run the server on UDP and TCP\n"
"Cars = 1 # Max cars for every player\n"
"MaxPlayers = 10 # Maximum Amount of Clients\n"
"Map = \"/levels/gridmap/info.json\" # Default Map\n"
"Name = \"BeamMP New Server\" # Server Name\n"
"Desc = \"BeamMP Default Description\" # Server Description\n"
"use = \"Resources\" # Resource file name\n"
"AuthKey = \"\" # Auth Key";
FileStream.close();
}
std::string RemoveComments(const std::string& Line){
std::string Return;
for(char c : Line) {
if(c == '#'){break;} //when it finds the # it will stop
Return += c;
}
return Return; //Converts it from a char array to string and returns it
}

View File

@ -1,17 +0,0 @@
///
/// Created by Anonymous275 on 4/1/2020
///
#include <vector>
std::vector<std::string> Split(const std::string& String,const std::string& delimiter){
std::vector<std::string> Val;
size_t pos = 0;
std::string token,s = String;
while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
Val.push_back(token);
s.erase(0, pos + delimiter.length());
}
Val.push_back(s);
return Val;
}

View File

@ -1,76 +0,0 @@
///
/// Created by Mitch on 04/02/2020
///
#include <thread>
#include <iostream>
#include <chrono>
#include "logger.h"
#include "Settings.hpp"
#include "Network 2.0/Client.hpp"
extern std::string StatReport;
std::string HTTP_REQUEST(const std::string&,int);
std::string PostHTTP(const std::string& IP,const std::string& Fields);
int Beat = 0;
std::string HTA(const std::string& hex)
{
std::string ascii;
for (size_t i = 0; i < hex.length(); i += 2)
{
std::string part = hex.substr(i, 2);
char ch = stoul(part, nullptr, 16);
ascii += ch;
}
return ascii;
}
std::string GetPlayers(){
std::string Return;
for(Client* c : Clients){
Return += c->GetName() + ";";
}
return Return;
}
void Heartbeat(){
std::string State,R,T;
while(true){
State = Private ? "true" : "false";
R = "uuid="+Key+"&players="+std::to_string(Clients.size())+"&maxplayers="+std::to_string(MaxPlayers)+"&port="
+ std::to_string(Port) + "&map=" + MapName + "&private="+State+"&version="+ServerVersion+
"&clientversion="+ClientVersion+"&name="+ServerName+"&pps="+StatReport+"&modlist="+FileList+
"&modstotalsize="+std::to_string(MaxModSize)+"&modstotal="+std::to_string(ModsLoaded)
+"&playerslist="+GetPlayers()+"&desc="+ServerDesc;
if(!CustomIP.empty())R+="&ip="+CustomIP;
//https://beamng-mp.com/heartbeatv2
T = PostHTTP(HTA("68747470733a2f2f6265616d6e672d6d702e636f6d2f6865617274626561747632"),R);
if(T.find_first_not_of("20") != std::string::npos){
//Backend system refused server startup!
if(Beat > 50)Beat = 1;
else Beat++;
std::this_thread::sleep_for(std::chrono::seconds(10));
if(Beat > 50)Beat = 1;
else Beat++;
T = PostHTTP(HTA("68747470733a2f2f6265616d6e672d6d702e636f6d2f6865617274626561747632"),R);
if(T.find_first_not_of("20") != std::string::npos){
error(HTA("4261636b656e642073797374656d20726566757365642073657276657221"));
std::this_thread::sleep_for(std::chrono::seconds(3));
exit(-1);
}
}
//Server Authenticated
if(T.length() == 4)info(HTA("5365727665722061757468656e746963617465642077697468206261636b656e64"));
R.clear();
T.clear();
State.clear();
if(Beat > 50)Beat = 1;
else Beat++;
std::this_thread::sleep_for(std::chrono::seconds(3));
}
}
void HeartbeatInit()
{
std::thread HB(Heartbeat);
HB.detach();
}

View File

@ -1,101 +1,80 @@
///
/// Created by jojos38 on 28/01/2020
/// Created by Anonymous275 on 7/17/2020
///
#include "Security/Enc.h"
#include "Settings.h"
#include "Logger.h"
#include <fstream>
#include "logger.h"
#include <string>
void addToLog(const std::string& Data);
int loggerlevel;
void setLoggerLevel(int level) {
//0 ALL 1 DEBUG 2 INFO 3 WARN 4 ERROR 5 OFF
loggerlevel = level;
}
std::stringstream getDate() {
// current date/time based on current system
time_t now = time(nullptr);
tm* ltm = localtime(&now);
int month = 1 + ltm->tm_mon;
int day = ltm->tm_mday;
int hours = ltm->tm_hour;
int minutes = ltm->tm_min;
int seconds = ltm->tm_sec;
std::string month_string;
if (month < 10) month_string = "0" + std::to_string(month);
else month_string = std::to_string(month);
std::string day_string;
if (day < 10) day_string = "0" + std::to_string(day);
else day_string = std::to_string(day);
std::string hours_string;
if (hours < 10) hours_string = "0" + std::to_string(hours);
else hours_string = std::to_string(hours);
std::string minutes_string;
if (minutes < 10) minutes_string = "0" + std::to_string(minutes);
else minutes_string = std::to_string(minutes);
std::string seconds_string;
if (seconds < 10) seconds_string = "0" + std::to_string(seconds);
else seconds_string = std::to_string(seconds);
#include <sstream>
#include <chrono>
std::string getDate() {
typedef std::chrono::duration<int, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>::type> days;
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::duration tp = now.time_since_epoch();
days d = std::chrono::duration_cast<days>(tp);tp -= d;
auto h = std::chrono::duration_cast<std::chrono::hours>(tp);tp -= h;
auto m = std::chrono::duration_cast<std::chrono::minutes>(tp);tp -= m;
auto s = std::chrono::duration_cast<std::chrono::seconds>(tp);tp -= s;
time_t tt = std::chrono::system_clock::to_time_t(now);
tm local_tm{};
localtime_s(&local_tm,&tt);
std::stringstream date;
int S = local_tm.tm_sec;
int M = local_tm.tm_min;
int H = local_tm.tm_hour;
std::string Secs = (S > 9 ? std::to_string(S) : "0" + std::to_string(S));
std::string Min = (M > 9 ? std::to_string(M) : "0" + std::to_string(M));
std::string Hour = (H > 9 ? std::to_string(H) : "0" + std::to_string(H));
date
<< "["
<< day_string << "/"
<< month_string << "/"
<< 1900 + ltm->tm_year << " "
<< hours_string << ":"
<< minutes_string << ":"
<< seconds_string
<< local_tm.tm_mday << "/"
<< local_tm.tm_mon + 1 << "/"
<< local_tm.tm_year + 1900 << " "
<< Hour << ":"
<< Min << ":"
<< Secs
<< "] ";
return date;
return date.str();
}
void InitLog(){
std::ofstream LFS;
LFS.open (Sec("Server.log"));
if(!LFS.is_open()){
error(Sec("logger file init failed!"));
}else LFS.close();
}
void addToLog(const std::string& Line){
std::ofstream LFS;
LFS.open (Sec("Server.log"), std::ios_base::app);
LFS << Line.c_str();
LFS.close();
}
void info(const std::string& toPrint) {
if (loggerlevel <= 2){
std::string Print = getDate().str() + "[INFO] " + toPrint + "\n";
std::string Print = getDate() + Sec("[INFO] ") + toPrint + "\n";
std::cout << Print;
addToLog(Print);
}
}
void error(const std::string& toPrint) {
if (loggerlevel <= 4) {
std::string Print = getDate().str() + "[ERROR] " + toPrint + "\n";
std::cout << Print;
addToLog(Print);
}
}
void warn(const std::string& toPrint) {
if (loggerlevel <= 3) {
std::string Print = getDate().str() + "[WARN] " + toPrint + "\n";
std::cout << Print;
addToLog(Print);
}
}
void debug(const std::string& toPrint) {
if (loggerlevel <= 1) {
std::string Print = getDate().str() + "[DEBUG] " + toPrint + "\n";
if(!Debug)return;
std::string Print = getDate() + Sec("[DEBUG] ") + toPrint + "\n";
std::cout << Print;
addToLog(Print);
}
}
void Exception(unsigned long Code,char* Origin) {
char* hex_string = new char[100];
sprintf(hex_string, "%lX", Code); //convert number to hex
if (loggerlevel <= 4) {
std::string Print = getDate().str() + "[EXCEP] code " + hex_string + " Origin: "+ std::string(Origin) +"\n";
void warn(const std::string& toPrint){
std::string Print = getDate() + Sec("[WARN] ") + toPrint + "\n";
std::cout << Print;
addToLog(Print);
}
void error(const std::string& toPrint) {
static int ECounter = 0;
std::string Print = getDate() + Sec("[ERROR] ") + toPrint + "\n";
std::cout << Print;
addToLog(Print);
if(ECounter > 10)exit(7);
ECounter++;
}
void except(const std::string& toPrint) {
std::string Print = getDate() + Sec("[EXCEP] ") + toPrint + "\n";
std::cout << Print;
addToLog(Print);
}
}

View File

@ -1,74 +1,21 @@
///
/// Created by Anonymous275 on 28/01/2020
///
#include <string>
#include <chrono>
#include <fstream>
#include "logger.h"
#include <algorithm>
#include "Settings.hpp"
void DebugData();
void LogInit();
void ParseConfig();
void addToLog(const std::string& Data);
//void ServerMain(int Port, int MaxClients);
void HeartbeatInit();
std::string ServerVersion = "0.51";
std::string ClientVersion = "1.50";
std::string CustomIP;
void HandleResources(std::string path);
void StatInit();
void NetMain();
#include "Startup.h"
#include <thread>
#include <iostream>
[[noreturn]] void loop(){
while(true){
std::cout.flush();
std::this_thread::sleep_for(std::chrono::milliseconds(600));
}
}
int main(int argc, char* argv[]) {
if(argc > 1){
CustomIP = argv[1];
size_t n = std::count(CustomIP.begin(), CustomIP.end(), '.');
int p = CustomIP.find_first_not_of(".0123456789");
if(p != std::string::npos || n != 3 || CustomIP.substr(0,3) == "127"){
CustomIP.clear();
warn("IP Specified is invalid!");
}else info("Started with custom ip : " + CustomIP);
}
info("BeamMP Server Running version " + ServerVersion);
LogInit();
ParseConfig();
HandleResources(Resource);
HeartbeatInit();
if(Debug)DebugData();
setLoggerLevel(0); //0 for all
if(ModsLoaded){
info("Loaded "+std::to_string(ModsLoaded)+" Mods");
}
std::thread t1(loop);
t1.detach();
InitServer(argc,argv);
InitConfig();
InitLua();
InitRes();
HBInit();
StatInit();
NetMain();
}
void DebugData(){
debug(std::string("Debug : ") + (Debug?"true":"false"));
debug(std::string("Private : ") + (Private?"true":"false"));
debug("Port : " + std::to_string(Port));
debug("Max Cars : " + std::to_string(MaxCars));
debug("MaxPlayers : " + std::to_string(MaxPlayers));
debug("MapName : " + MapName);
debug("ServerName : " + ServerName);
debug("ServerDesc : " + ServerDesc);
debug("File : " + Resource);
debug("Auth Key : " + Key);
}
void LogInit(){
std::ofstream LFS;
LFS.open ("Server.log");
LFS.close();
}
void addToLog(const std::string& Data){
std::ofstream LFS;
LFS.open ("Server.log", std::ios_base::app);
LFS << Data.c_str();
LFS.close();
return 0;
}