mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-08-16 16:26:26 +00:00
V0.6
rewrite
This commit is contained in:
parent
232c4d7b28
commit
31c96cee94
2
.idea/.name
generated
2
.idea/.name
generated
@ -1 +1 @@
|
||||
BeamMP-Server
|
||||
Server
|
@ -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)
|
||||
|
@ -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
7
include/Compressor.h
Normal 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
7
include/Curl/Http.h
Normal 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);
|
@ -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
|
||||
|
@ -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 *);
|
@ -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);
|
@ -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
19
include/Network.h
Normal 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
16
include/Security/Enc.h
Normal 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
130
include/Security/Xor.h
Normal 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
|
@ -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
11
include/Startup.h
Normal 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
536
include/Zlib/zconf.h
Normal 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
1912
include/Zlib/zlib.h
Normal file
File diff suppressed because it is too large
Load Diff
271
include/Zlib/zutil.h
Normal file
271
include/Zlib/zutil.h
Normal 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
49
src/Compressor.cpp
Normal 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
113
src/Enc.cpp
Normal 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
149
src/Init/Config.cpp
Normal 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
59
src/Init/Heartbeat.cpp
Normal 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();
|
||||
}
|
@ -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
32
src/Init/Startup.cpp
Normal 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;
|
||||
}
|
@ -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"));
|
||||
}
|
@ -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){
|
@ -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()}});
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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
172
src/Network/Auth.cpp
Normal 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();
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
@ -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"))){}
|
||||
}
|
@ -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;
|
||||
}
|
82
src/Network/InitClient.cpp
Normal file
82
src/Network/InitClient.cpp
Normal 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
8
src/Network/NetMain.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "Network.h"
|
||||
#include <thread>
|
||||
ClientInterface* CI;
|
||||
void NetMain(){
|
||||
std::thread TCP(TCPServerMain);
|
||||
TCP.detach();
|
||||
UDPServerMain();
|
||||
}
|
43
src/Network/StatMonitor.cpp
Normal file
43
src/Network/StatMonitor.cpp
Normal 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();
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
52
src/Network/TCPHandler.cpp
Normal file
52
src/Network/TCPHandler.cpp
Normal 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();
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
132
src/config.cpp
132
src/config.cpp
@ -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
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
143
src/logger.cpp
143
src/logger.cpp
@ -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);
|
||||
}
|
||||
}
|
87
src/main.cpp
87
src/main.cpp
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user