Compare commits

..

2 Commits

Author SHA1 Message Date
Starystars67 6247191a3e Further Tidy of unused files 2020-01-28 23:16:33 +00:00
Starystars67 d752ac5acb Creation of NodeJS Branch 2020-01-28 23:04:21 +00:00
49 changed files with 1708 additions and 4350 deletions
-5
View File
@@ -1,5 +0,0 @@
---
BasedOnStyle: WebKit
BreakBeforeBraces: Attach
...
+74 -434
View File
@@ -1,464 +1,104 @@
boost_*
Resources
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
#VS Files
out/
#Clion Files
cmake-build-debug/CMakeFiles/
cmake-build-release/CMakeFiles/
cmake-build-debug/Resources/
cmake-build-release/Resources/
cmake-build-debug/*.*
cmake-build-release/*.*
cmake-build-debug/Makefile
cmake-build-release/Makefile
!cmake-build-debug/*.lib
!cmake-build-release/*.lib
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
# Logs
logs
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Chutzpah Test files
_Chutzpah*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Visual Studio Trace Files
*.e2e
# Coverage directory used by tools like istanbul
coverage
*.lcov
# TFS 2012 Local Workspace
$tf/
# nyc test coverage
.nyc_output
# Guidance Automation Toolkit
*.gpState
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# Bower dependency directory (https://bower.io/)
bower_components
# TeamCity is a build add-in
_TeamCity*
# node-waf configuration
.lock-wscript
# DotCover is a Code Coverage Tool
*.dotCover
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Dependency directories
node_modules/
jspm_packages/
# Visual Studio 6 build log
*.plg
# TypeScript v1 declaration files
typings/
# Visual Studio 6 workspace options file
*.opt
# TypeScript cache
*.tsbuildinfo
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Optional npm cache directory
.npm
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Optional eslint cache
.eslintcache
# Paket dependency manager
.paket/paket.exe
paket-files/
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# FAKE - F# Make
.fake/
# Optional REPL history
.node_repl_history
# CodeRush personal settings
.cr/personal
# Output of 'npm pack'
*.tgz
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Yarn Integrity file
.yarn-integrity
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# dotenv environment variables file
.env
.env.test
# Tabs Studio
*.tss
# parcel-bundler cache (https://parceljs.org/)
.cache
# Telerik's JustMock configuration file
*.jmconfig
# Next.js build output
.next
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# Nuxt.js build / generate output
.nuxt
dist
# OpenCover UI analysis results
OpenCover/
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# Azure Stream Analytics local run output
ASALocalRun/
# vuepress build output
.vuepress/dist
# MSBuild Binary and Structured Log
*.binlog
# Serverless directories
.serverless/
# NVidia Nsight GPU debugger configuration file
*.nvuser
# FuseBox cache
.fusebox/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# DynamoDB Local files
.dynamodb/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
out/build/x86-Debug/VSInheritEnvironments.txt
out/build/x86-Debug/rules.ninja
out/build/x86-Debug/CMakeFiles/untitled.dir/manifest.res
out/build/x86-Debug/CMakeFiles/untitled.dir/manifest.rc
out/build/x86-Debug/CMakeFiles/untitled.dir/intermediate.manifest
out/build/x86-Debug/CMakeFiles/untitled.dir/embed.manifest
out/build/x86-Debug/CMakeFiles/TargetDirectories.txt
out/build/x86-Debug/CMakeFiles/ShowIncludes/main.c
out/build/x86-Debug/CMakeFiles/ShowIncludes/foo.h
out/build/x86-Debug/CMakeFiles/cmake.check_cache
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CompilerIdCXX/CMakeCXXCompilerId.exe
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CompilerIdCXX/CMakeCXXCompilerId.cpp
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CompilerIdC/CMakeCCompilerId.exe
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CompilerIdC/CMakeCCompilerId.c
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeSystem.cmake
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeRCCompiler.cmake
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeDetermineCompilerABI_CXX.bin
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeDetermineCompilerABI_C.bin
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeCXXCompiler.cmake
out/build/x86-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeCCompiler.cmake
out/build/x86-Debug/CMakeCache.txt
out/build/x86-Debug/cmake_install.cmake
out/build/x86-Debug/build.ninja
out/build/x86-Debug/.ninja_log
out/build/x86-Debug/.ninja_deps
out/build/x86-Debug/.cmake/api/v1/reply/target-untitled-Debug-03f16c5921ae0bd48990.json
out/build/x86-Debug/.cmake/api/v1/reply/index-2020-01-27T23-42-34-0718.json
out/build/x86-Debug/.cmake/api/v1/reply/codemodel-v2-2b93246ca751d7a49cd1.json
out/build/x86-Debug/.cmake/api/v1/reply/cmakeFiles-v1-d93b224eb363971ee2c4.json
out/build/x86-Debug/.cmake/api/v1/reply/cache-v2-43521627501184045d13.json
out/build/x86-Debug/.cmake/api/v1/query/client-MicrosoftVS/query.json
out/build/x64-Debug/VSInheritEnvironments.txt
out/build/x64-Debug/rules.ninja
out/build/x64-Debug/CMakeFiles/untitled.dir/manifest.res
out/build/x64-Debug/CMakeFiles/untitled.dir/manifest.rc
out/build/x64-Debug/CMakeFiles/untitled.dir/intermediate.manifest
out/build/x64-Debug/CMakeFiles/untitled.dir/embed.manifest
out/build/x64-Debug/CMakeFiles/TargetDirectories.txt
out/build/x64-Debug/CMakeFiles/ShowIncludes/main.c
out/build/x64-Debug/CMakeFiles/ShowIncludes/foo.h
out/build/x64-Debug/CMakeFiles/cmake.check_cache
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CompilerIdCXX/CMakeCXXCompilerId.exe
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CompilerIdCXX/CMakeCXXCompilerId.cpp
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CompilerIdC/CMakeCCompilerId.exe
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CompilerIdC/CMakeCCompilerId.c
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeSystem.cmake
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeRCCompiler.cmake
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeDetermineCompilerABI_CXX.bin
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeDetermineCompilerABI_C.bin
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeCXXCompiler.cmake
out/build/x64-Debug/CMakeFiles/3.15.19101501-MSVC_2/CMakeCCompiler.cmake
out/build/x64-Debug/CMakeCache.txt
out/build/x64-Debug/cmake_install.cmake
out/build/x64-Debug/build.ninja
out/build/x64-Debug/.ninja_log
out/build/x64-Debug/.ninja_deps
out/build/x64-Debug/.cmake/api/v1/reply/target-untitled-Debug-8918286eee207fe0275b.json
out/build/x64-Debug/.cmake/api/v1/reply/index-2020-01-27T23-42-03-0431.json
out/build/x64-Debug/.cmake/api/v1/reply/codemodel-v2-ee254da00ecbf4b22928.json
out/build/x64-Debug/.cmake/api/v1/reply/cmakeFiles-v1-ee926bd040d82c324cbe.json
out/build/x64-Debug/.cmake/api/v1/reply/cache-v2-6f7cb0917968b934d35c.json
out/build/x64-Debug/.cmake/api/v1/query/client-MicrosoftVS/query.json
CMakeSettings.json
cmake-build-debug/Resource1.resx
out/build/x64-Debug/.cmake/api/v1/reply/index-2020-01-28T10-34-19-0746.json
out/build/x64-Debug/untitled.exe
out/build/x64-Debug/.cmake/api/v1/reply/index-2020-01-28T11-19-41-0061.json
out/build/x64-Debug/.cmake/api/v1/reply/cmakeFiles-v1-52c1d9386071c1490278.json
out/build/x86-Debug/CMakeFiles/cmake-main.dir/manifest.res
out/build/x86-Debug/CMakeFiles/cmake-main.dir/manifest.rc
out/build/x86-Debug/CMakeFiles/cmake-main.dir/intermediate.manifest
out/build/x86-Debug/CMakeFiles/cmake-main.dir/embed.manifest
out/build/x86-Debug/cmake-main.exe
out/build/x86-Debug/.cmake/api/v1/reply/target-enet-Debug-1cc90e5d191bd520f961.json
out/build/x86-Debug/.cmake/api/v1/reply/target-cmake-main-Debug-0c9bd3464adc40e447af.json
out/build/x86-Debug/.cmake/api/v1/reply/index-2020-01-28T11-21-26-0362.json
out/build/x86-Debug/.cmake/api/v1/reply/codemodel-v2-1850e17888d5bab56568.json
out/build/x86-Debug/.cmake/api/v1/reply/cmakeFiles-v1-7c376457f6b736ad28ac.json
out/build/x64-Debug/CMakeFiles/cmake-main.dir/manifest.res
out/build/x64-Debug/CMakeFiles/cmake-main.dir/manifest.rc
out/build/x64-Debug/CMakeFiles/cmake-main.dir/intermediate.manifest
out/build/x64-Debug/CMakeFiles/cmake-main.dir/embed.manifest
out/build/x64-Debug/cmake-main.exe
out/build/x64-Debug/.cmake/api/v1/reply/target-enet-Debug-645fd45f5bd4fab53aa9.json
out/build/x64-Debug/.cmake/api/v1/reply/target-cmake-main-Debug-b124668c8fb6ca5df286.json
out/build/x64-Debug/.cmake/api/v1/reply/index-2020-01-28T11-21-06-0706.json
out/build/x64-Debug/.cmake/api/v1/reply/codemodel-v2-63a6ab1789a1732f4563.json
out/build/x86-Debug/.cmake/api/v1/reply/target-enet-Debug-d301abed48f6c38bdcfb.json
out/build/x86-Debug/.cmake/api/v1/reply/index-2020-01-28T12-30-44-0946.json
out/build/x86-Debug/.cmake/api/v1/reply/codemodel-v2-3eaabe43603befc605b1.json
out/build/x86-Debug/.cmake/api/v1/reply/target-cmake-main-Debug-70eff68e1e381b42992e.json
*.xml
out/build/x86-Debug/.cmake/api/v1/reply/target-enet-Debug-48db38ae5d08e27876b8.json
out/build/x86-Debug/.cmake/api/v1/reply/target-cmake-main-Debug-540e487569703b71c785.json
out/build/x86-Debug/.cmake/api/v1/reply/index-2020-01-28T17-35-38-0764.json
out/build/x86-Debug/.cmake/api/v1/reply/codemodel-v2-6a61e390ef8eaf17e9f8.json
out/build/x86-Debug/Server.cfg
*Server.cfg*
# TernJS port file
.tern-port
-2
View File
@@ -1,2 +0,0 @@
# Default ignored files
/workspace.xml
Generated
-1
View File
@@ -1 +0,0 @@
Server
-2
View File
@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/BeamNG-MP-Server.iml" filepath="$PROJECT_DIR$/.idea/BeamNG-MP-Server.iml" />
</modules>
</component>
</project>
Generated
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
-39
View File
@@ -1,39 +0,0 @@
cmake_minimum_required(VERSION 3.10)
project(Server)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -static-libstdc++")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -g")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s")
elseif (WIN32)
# This might cause issues with old windows headers, but it's worth the trouble to keep the code
# completely cross platform. For fixes to common issues arising from /permissive- visit:
# https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance
message(${CMAKE_CXX_FLAGS_RELEASE})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /permissive-")
message(STATUS "MSVC -> forcing use of statically-linked runtime.")
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
#-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
endif ()
find_package(Boost 1.70.0 REQUIRED COMPONENTS system thread)
file(GLOB source_files "src/*.cpp" "src/*/*.cpp" "include/*.h" "include/*/*.h" "include/*.hpp" "include/*/*.hpp")
add_executable(BeamMP-Server ${source_files})
target_include_directories(BeamMP-Server SYSTEM PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
find_package(Lua 5.3 REQUIRED)
target_include_directories(BeamMP-Server SYSTEM PUBLIC ${LUA_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
if (UNIX)
target_link_libraries(BeamMP-Server z pthread stdc++fs ${Boost_LINK_DIRS} lua curl dl)
elseif (WIN32)
include(FindLua)
find_package(CURL CONFIG REQUIRED)
find_package(ZLIB REQUIRED)
target_link_libraries(BeamMP-Server PRIVATE urlmon ws2_32 CURL::libcurl ZLIB::ZLIB ${Boost_LINK_DIRS} ${LUA_LIBRARIES})
endif ()
+1 -36
View File
@@ -1,36 +1 @@
# BeamNG-MP-Server
## Unix specific build instructions
1. You need boost >= 1.70.0
Check with your ditro's package manager whether it provides this. If it does, you should use that.
If it doesnt provide it or you want to link it statically (like we do with our releases), then you have to do this:
download the latest boost source code.
Then, go to the downloaded directory and run
```sh
b2 link=static runtime-link=static threading=multi
```
And then either symlink, edit CMakeLists to find it, or simply run
```sh
b2 link=static runtime-link=static threading=multi install
```
(warning: installs boost into your system, you might not want this).
Then on invocation of cmake, ensure that you define `Boost_USE_STATIC_RUNTIME=ON`.
2. Building
Run cmake, and then make.
Example:
```bash
~/src/Server $ cmake -S . -B bin -DCMAKE_BUILD_TYPE=Release
...
~/src/Server $ make -C bin -j 5
```
# BeamNG-MP-Server
Binary file not shown.
-85
View File
@@ -1,85 +0,0 @@
///
/// Created by Anonymous275 on 5/8/2020
///
#pragma once
#ifdef WIN32
#include <WS2tcpip.h>
#else
#include <arpa/inet.h>
#define SOCKET int
#endif
#include "CustomAssert.h"
#include <string>
#include <vector>
#include <chrono>
#include <set>
#include <algorithm>
struct VData{
int ID = -1;
std::string Data;
};
class Client {
private:
std::set<std::unique_ptr<VData>> VehicleData; //ID and Data;
std::string Name = Sec("Unknown Client");
sockaddr_in UDPADDR;
std::string Role;
std::string DID;
SOCKET TCPSOCK;
int Status = 0;
int ID = -1;
public:
void AddNewCar(int ident,const std::string& Data);
void SetCarData(int ident,const std::string&Data);
void SetName(const std::string& name);
void SetRole(const std::string& role);
void SetDID(const std::string& did);
std::string GetCarData(int ident);
void SetUDPAddr(sockaddr_in Addr);
std::set<std::unique_ptr<VData>>& GetAllCars();
const std::set<std::unique_ptr<VData>>& GetAllCars() const;
void SetTCPSock(SOCKET CSock);
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();
void SetID(int ID);
int GetOpenCarID();
int GetCarCount();
void ClearCars();
int GetStatus();
int GetID();
};
struct ClientInterface{
std::set<std::unique_ptr<Client>> Clients;
void RemoveClient(Client*& c){
Assert(c);
c->ClearCars();
auto Iter = std::find_if(Clients.begin(), Clients.end(), [&](auto& ptr) {
return c == ptr.get();
});
Assert(Iter != Clients.end());
if (Iter == Clients.end()) {
return;
}
Clients.erase(Iter);
c = nullptr;
}
void AddClient(Client*&& c){
Assert(c);
Clients.insert(std::move(std::unique_ptr<Client>(c)));
}
int Size(){
return int(Clients.size());
}
};
extern std::unique_ptr<ClientInterface> CI;
-7
View File
@@ -1,7 +0,0 @@
///
/// Created by Anonymous275 on 7/24/2020
///
#pragma once
#include <string>
std::string Comp(std::string Data);
std::string DeComp(std::string Compressed);
-7
View File
@@ -1,7 +0,0 @@
///
/// 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);
-67
View File
@@ -1,67 +0,0 @@
// Author: lionkor
/*
* Asserts are to be used anywhere where assumptions about state are made
* implicitly. AssertNotReachable is used where code should never go, like in
* default switch cases which shouldn't trigger. They make it explicit
* that a place cannot normally be reached and make it an error if they do.
*/
#pragma once
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <thread>
#include "Logger.h"
static const char* const ANSI_RESET = "\u001b[0m";
static const char* const ANSI_BLACK = "\u001b[30m";
static const char* const ANSI_RED = "\u001b[31m";
static const char* const ANSI_GREEN = "\u001b[32m";
static const char* const ANSI_YELLOW = "\u001b[33m";
static const char* const ANSI_BLUE = "\u001b[34m";
static const char* const ANSI_MAGENTA = "\u001b[35m";
static const char* const ANSI_CYAN = "\u001b[36m";
static const char* const ANSI_WHITE = "\u001b[37m";
static const char* const ANSI_BLACK_BOLD = "\u001b[30;1m";
static const char* const ANSI_RED_BOLD = "\u001b[31;1m";
static const char* const ANSI_GREEN_BOLD = "\u001b[32;1m";
static const char* const ANSI_YELLOW_BOLD = "\u001b[33;1m";
static const char* const ANSI_BLUE_BOLD = "\u001b[34;1m";
static const char* const ANSI_MAGENTA_BOLD = "\u001b[35;1m";
static const char* const ANSI_CYAN_BOLD = "\u001b[36;1m";
static const char* const ANSI_WHITE_BOLD = "\u001b[37;1m";
static const char* const ANSI_BOLD = "\u001b[1m";
static const char* const ANSI_UNDERLINE = "\u001b[4m";
#if DEBUG
inline void _assert([[maybe_unused]] const char* file, [[maybe_unused]] const char* function, [[maybe_unused]] unsigned line,
[[maybe_unused]] const char* condition_string, [[maybe_unused]] bool result) {
if (!result) {
std::cout << std::flush << "(debug build) TID "
<< std::this_thread::get_id() << ": ASSERTION FAILED: at "
<< file << ":" << line << " \n\t-> in "
<< function << ", Line " << line << ": \n\t\t-> "
<< "Failed Condition: " << condition_string << std::endl;
std::cout << "... terminating ..." << std::endl;
abort();
}
}
#define Assert(cond) _assert(__FILE__, __func__, __LINE__, #cond, (cond))
#define AssertNotReachable() _assert(__FILE__, __func__, __LINE__, "reached unreachable code", false)
#else
// In release build, these macros turn into NOPs. The compiler will optimize these out.
#define Assert(x) \
do { \
} while (false)
#define AssertNotReachable() \
do { \
} while (false)
#endif // DEBUG
-18
View File
@@ -1,18 +0,0 @@
///
/// Created by Anonymous275 on 4/2/2020.
///
#pragma once
#include "Security/Xor.h"
#include <iostream>
#include <mutex>
#include <string>
void InitLog();
#define DebugPrintTID() DebugPrintTIDInternal(__func__, false)
void DebugPrintTIDInternal(const std::string& func, bool overwrite = true); // prints the current thread id in debug mode, to make tracing of crashes and asserts easier
void ConsoleOut(const std::string& msg);
void QueueAbort();
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);
-77
View File
@@ -1,77 +0,0 @@
///
/// Created by Anonymous275 on 5/20/2020
///
#pragma once
#include <any>
#include <filesystem>
#include <iostream>
#include <lua.hpp>
#include <memory>
#include <mutex>
#include <set>
#include <thread>
#include <vector>
namespace fs = std::filesystem;
struct LuaArg {
std::vector<std::any> args;
void PushArgs(lua_State* State) {
for (std::any arg : args) {
if (!arg.has_value())
return;
std::string Type = arg.type().name();
if (Type.find("bool") != std::string::npos) {
lua_pushboolean(State, std::any_cast<bool>(arg));
}
if (Type.find("basic_string") != std::string::npos || Type.find("char") != std::string::npos) {
lua_pushstring(State, std::any_cast<std::string>(arg).c_str());
}
if (Type.find("int") != std::string::npos) {
lua_pushinteger(State, std::any_cast<int>(arg));
}
if (Type.find("float") != std::string::npos) {
lua_pushnumber(State, std::any_cast<float>(arg));
}
}
}
};
class Lua {
private:
std::set<std::pair<std::string, std::string>> _RegisteredEvents;
lua_State* luaState { nullptr };
fs::file_time_type _LastWrote;
std::string _PluginName {};
std::string _FileName {};
bool _StopThread = false;
bool _Console = false;
public:
void Init();
void RegisterEvent(const std::string& Event, const std::string& FunctionName);
std::string GetRegistered(const std::string& Event) const;
void UnRegisterEvent(const std::string& Event);
void SetLastWrite(fs::file_time_type time);
bool IsRegistered(const std::string& Event);
void SetPluginName(const std::string& Name);
void Execute(const std::string& Command);
void SetFileName(const std::string& Name);
fs::file_time_type GetLastWrite();
std::string GetPluginName() const;
std::string GetFileName() const;
lua_State* GetState();
const lua_State* GetState() const;
std::string GetOrigin();
std::mutex Lock;
void Reload();
Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console = false);
Lua(bool Console = false);
~Lua();
void SetStopThread(bool StopThread) { _StopThread = StopThread; }
bool GetStopThread() const { return _StopThread; }
};
int CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr<LuaArg> args);
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr<LuaArg> arg, bool Wait);
extern std::set<std::unique_ptr<Lua>> PluginEngine;
-19
View File
@@ -1,19 +0,0 @@
///
/// 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, 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);
-19
View File
@@ -1,19 +0,0 @@
// Author: lionkor
#pragma once
/*
* An RWMutex allows multiple simultaneous readlocks but only one writelock at a time,
* and write locks and read locks are mutually exclusive.
*/
#include <shared_mutex>
// Use ReadLock(m) and WriteLock(m) to lock it.
using RWMutex = std::shared_mutex;
// Construct with an RWMutex as a non-const reference.
// locks the mutex in lock_shared mode (for reading). Locking in a thread that already owns a lock
// i.e. locking multiple times successively is UB. Construction may be blocking. Destruction is guaranteed to release the lock.
using ReadLock = std::shared_lock<RWMutex>;
// Construct with an RWMutex as a non-const reference.
// locks the mutex for writing. Construction may be blocking. Destruction is guaranteed to release the lock.
using WriteLock = std::unique_lock<RWMutex>;
-21
View File
@@ -1,21 +0,0 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#pragma once
#ifdef __linux
#define EXCEPTION_POINTERS void
#else
#include <WS2tcpip.h>
#endif
#include "Xor.h"
#include <string>
struct RSA {
int n = 0;
int e = 0;
int d = 0;
};
std::string RSA_E(const std::string& Data, int e, int n);
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();
-132
View File
@@ -1,132 +0,0 @@
///
/// Created by Anonymous275 on 8/11/2020
///
#pragma once
#include <array>
#include <cstdarg>
#include <cstdio>
#include <string>
#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 inline XorString(const Char* str, std::index_sequence<Is...>)
: _key(RandomChar<K>::value)
, _encrypted { enc(str[Is])... } { }
inline 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(fmt, args);
va_end(args);
};
static auto w_printf_s = [](const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(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);
vsnprintf(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 = vsnprintf(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
-24
View File
@@ -1,24 +0,0 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#pragma once
#include <string>
extern std::string ServerName;
extern std::string ServerDesc;
extern std::string StatReport;
extern std::string FileSizes;
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 bool Private;
extern int MaxCars;
extern bool Debug;
extern int Port;
extern int PPS;
-12
View File
@@ -1,12 +0,0 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#pragma once
void InitServer(int argc, char* argv[]);
void ConsoleInit();
void InitConfig();
void InitLua();
void InitRes();
void HBInit();
void StatInit();
void NetMain();
-38
View File
@@ -1,38 +0,0 @@
// Author: lionkor
#pragma once
// This header defines unix equivalents of common win32 functions.
#ifndef WIN32
#include "CustomAssert.h"
#include <cstring>
#include <sys/socket.h>
#include <unistd.h>
// ZeroMemory is just a {0} or a memset(addr, 0, len), and it's a macro on MSVC
inline void ZeroMemory(void* dst, size_t len) {
Assert(std::memset(dst, 0, len) != nullptr);
}
// provides unix equivalent of closesocket call in win32
inline void CloseSocketProper(int socket) {
shutdown(socket, SHUT_RDWR);
close(socket);
}
#ifndef __try
#define __try
#endif
#ifndef __except
#define __except (x) /**/
#endif
#else // win32
inline void CloseSocketProper(uint64_t socket) {
shutdown(socket, SD_BOTH);
closesocket(socket);
}
#endif // WIN32
+345
View File
@@ -0,0 +1,345 @@
// Server Settings!
var map = "";
let _VERSION = "0.0.3"
let UDPExpireTime = 30// In Seconds
const net = require('net');
const uuidv4 = require('uuid/v4');
const args = require('minimist')(process.argv.slice(2));
const chalk = require("chalk")
//console.log(args.port)
if (args.port) {
var tcpport = args.port;
} else {
var tcpport = 30813;
}
var udpport = tcpport + 1;
var wsport = tcpport + 2;
const host = '0.0.0.0';
//==========================================================
// WebSocket Server
//==========================================================
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: wsport });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('[WS] received: %s', message);
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
});
ws.send('Welcome!');
});
console.log(chalk.cyan('[WS]')+' Server listening on 0.0.0.0:' + wsport);
//==========================================================
// TCP Server
//==========================================================
const TCPserver = net.createServer();
TCPserver.listen(tcpport, () => {
console.log(chalk.green('[TCP]')+' Server listening on 0.0.0.0:' + tcpport);
});
let sockets = [];
let players = [];
let names = [];
let vehicles = [];
TCPserver.on('connection', function(sock) {
console.log(chalk.green('[TCP]')+' CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sockets.push(sock);
var player = {};
player.remoteAddress = sock.remoteAddress;
player.remotePort = sock.remotePort;
player.nickname = "New User, Loading...";
player.id = uuidv4();
player.currentVehID = 0;
players.push(player);
sock.write('HOLA'+player.id+'\n');
if (map == "") {
sock.write("MAPS\n");
} else {
sock.write("MAPC"+map+'\n')
}
sock.write("VCHK"+_VERSION+'\n')
sock.on('data', function(data) {
// Write the data back to all the connected, the client will receive it as data from the server
var str = data.toString();
data = str.trim(); //replace(/\r?\n|\r/g, "");
var code = data.substring(0, 4);
var message = data.substr(4);
if (code != "PING") {
//console.log(code)
}
//if (data.length > 4) {
//console.log(data.length)
//}
switch (code) {
case "PING":
//console.log("Ping Received")
sock.write('PONG\n');
break;
case "CHAT":
sockets.forEach(function(socket, index, array) { // Send update to all clients
socket.write(data+'\n');
});
break;
case "MAPS":
map = message;
console.log("Setting map to: "+map);
sock.write("MAPC"+map+'\n');
break;
case "USER":
players.forEach(function(player, index, array) {
if (player.remoteAddress == sock.remoteAddress && player.remotePort == sock.remotePort) {
console.log("Player Found ("+player.id+"), setting nickname("+data.substr(4)+")");
player.nickname = ""+data.substr(4)+"";
sockets.forEach(function(socket, index, array) { // Send update to all clients
socket.write('PLST'+JSON.stringify(players)+'\n');
socket.write('SMSG'+data.substr(4)+' Just Joined the Session.\n');
});
}
});
break;
case "QUIT":
case "2001":
let index = sockets.findIndex(function(o) {
return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
})
if (index !== -1) sockets.splice(index, 1);
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
break;
case "U-VI":
case "U-VE":
case "U-VN":
case "U-VP":
case "U-VL":
case "U-VR":
case "U-VV":
//console.log(data)
//players.forEach(function(player, index, array) {
//if (player.remoteAddress != sock.remoteAddress) {
//console.log(player.remoteAddress+' != '+sock.remoteAddress+' Is not the same so we should send?')
//console.log("Got Update to send!")
sockets.forEach(function(socket, index, array) { // Send update to all clients
//console.log(socket.remotePort+' != '+sock.remotePort+' Is not the same so we should send?')
if ((sock.remoteAddress != socket.remoteAddress && sock.remotePort != socket.remotePort) || (sock.remoteAddress == socket.remoteAddress && sock.remotePort != socket.remotePort)) {
socket.write(data+'\n');
}
});
//}
//});
break;
case "U-VC":
sockets.forEach(function(socket, index, array) { // Send update to all clients
socket.write(data+'\n');
});
break;
case "U-NV":
console.log(message)
var vid = uuidv4();
break;
case "C-VS": // Client has changed vehicle. lets update our records.
console.log(message)
players.forEach(function(player, index, array) {
if (player.currentVehID != message && player.remoteAddress == sock.remoteAddress && player.remotePort == sock.remotePort) {
console.log(chalk.green('[TCP]')+" Player Found ("+player.id+"), updating current vehile("+message+")");
player.currentVehID = message;
}
});
break;
default:
console.log(chalk.green('[TCP]')+' Unknown / unhandled data from:' + sock.remoteAddress);
console.log(chalk.green('[TCP]')+' Data -> ' + data);
sockets.forEach(function(socket, index, array) { // Send update to all clients
//if ((sock.remoteAddress != socket.remoteAddress && sock.remotePort != socket.remotePort) || (sock.remoteAddress == socket.remoteAddress && sock.remotePort != socket.remotePort)) {
socket.write(data+'\n');
//}
});
break;
}
sockets.forEach(function(sock, index, array) {
//sock.write(sock.remoteAddress + ':' + sock.remotePort + " said " + data + '\n');
});
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
var index = players.findIndex(function(o) {
return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
})
if (index !== -1) sockets.splice(index, 1);
index = sockets.findIndex(function(o) {
return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
})
if (index !== -1) sockets.splice(index, 1);
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
players = removePlayer(players, sock.remoteAddress);
console.log("Player list now holds: "+JSON.stringify(players));
sockets.forEach(function(socket, index, array) { // Send update to all clients
socket.write('PLST'+JSON.stringify(players)+'\n');
});
});
sock.on('error', (err) => {
// handle errors here
if (err.code == "ECONNRESET") {
console.error(chalk.red("ERROR ")+"Connection Reset for player: ");
players.forEach(function(player, index, array) {
if (player.remoteAddress == sock.remoteAddress && player.remotePort == sock.remotePort) {
console.error(+player.nickname+" ("+player.id+")");
console.error(chalk.red("ERROR ")+"End Error.");
}
});
} else {
console.error("Sock Error");
console.error(err);
throw err;
}
});
});
TCPserver.on('error', (err) => {
// handle errors here
console.error("TCPserver Error");
console.error(err);
throw err;
});
function removePlayer(array, ip) {
return array.filter(player => player.remoteAddress != ip);
}
//==========================================================
// UDP Server
//==========================================================
var clients = {};
var intervalTime = UDPExpireTime*2*1000;
setInterval(function() {
console.log(clients);
for (var client in clients) {
var lastupdate = clients[client];
var millis = Date.now() - lastupdate;
var t = Math.floor(millis/1000)
if (t > UDPExpireTime) {
console.warn("Found Old Client: "+client)
delete clients[client];
}
}
}, intervalTime);
function updateClient (rinfo) {
for (var client in clients) {
client = JSON.parse(client);
var address = client[0];
var port = client[1];
if (port == rinfo.port && address == rinfo.address) {
client
}
}
}
var dgram = require('dgram');
var UDPserver = dgram.createSocket('udp4');
function UDPsend(message, info) {
UDPserver.send(message, 0, message.length, info.port, info.address, function(error){
if (error) {
console.log("ERROR");
console.log(error);
client.close();
};
});
}
UDPserver.on('listening', function() {
var address = UDPserver.address();
console.log(chalk.rgb(123, 45, 67)('[UDP]')+' Server listening on ' + address.address + ':' + address.port);
});
UDPserver.on('message',function(msg,rinfo){
clients[JSON.stringify([rinfo.address, rinfo.port])] = Date.now();
//sending msg
var str = msg.toString();
data = str.trim(); //replace(/\r?\n|\r/g, "");
var code = data.substring(0, 4);
//if (code != "PING") {
//console.log(msg.toString());
//}
switch (code) {
case "PING":
UDPsend("PONG", rinfo)
break;
case "U-VC":
for (var client in clients) {
client = JSON.parse(client);
var port = client[1];
var address = client[0];
UDPserver.send(msg, 0, msg.length, port, address, function(error){
if (error) {
console.log("ERROR");
console.log(error);
client.close();
};
});
}
break;
case "U-VR":
case "U-VL":
case "U-VP":
case "U-VN":
case "U-VE":
case "U-VI":
for (var client in clients) {
client = JSON.parse(client);
var port = client[1];
var address = client[0];
if (port != rinfo.port && address != rinfo.address) {
UDPserver.send(msg, 0, msg.length, port, address, function(error){
if (error) {
console.log("ERROR");
console.log(error);
client.close();
};
});
}
}
break;
default:
// Unhandled data, this at the moment includes the extra packets of vehicles so it needs to be here until it is handled correctly
for (var client in clients) {
client = JSON.parse(client);
var port = client[1];
var address = client[0];
UDPserver.send(msg, 0, msg.length, port, address, function(error){
if (error) {
console.log("ERROR");
console.log(error);
client.close();
};
});
}
//console.log(chalk.rgb(123, 45, 67)('[UDP]')+' Data received from client : ' + msg.toString());
//console.log(chalk.rgb(123, 45, 67)('[UDP]')+' Received %d bytes from %s:%d\n',msg.length, rinfo.address, rinfo.port);
}
});
UDPserver.bind(Number(udpport));
+1268
View File
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
{
"name": "beamng.drive-mp-server",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"author": "Mitch Durso",
"license": "ISC",
"devDependencies": {
"electron": "^6.0.7"
},
"dependencies": {
"chalk": "^3.0.0",
"minimist": "^1.2.0",
"uuid": "^3.3.3",
"ws": "^7.2.1"
}
}
-52
View File
@@ -1,52 +0,0 @@
///
/// Created by Anonymous275 on 7/15/2020
///
#include <algorithm>
#include <array>
#include <iostream>
#include <zlib.h>
#define Biggest 30000
std::string Comp(std::string Data) {
std::array<char, Biggest> C {};
// obsolete
C.fill(0);
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.data());
deflateInit(&defstream, Z_BEST_COMPRESSION);
deflate(&defstream, Z_SYNC_FLUSH);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);
size_t TO = defstream.total_out;
std::string Ret(TO, 0);
std::copy_n(C.begin(), TO, Ret.begin());
return Ret;
}
std::string DeComp(std::string Compressed) {
std::array<char, Biggest> C {};
// not needed
C.fill(0);
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.data());
inflateInit(&infstream);
inflate(&infstream, Z_SYNC_FLUSH);
inflate(&infstream, Z_FINISH);
inflateEnd(&infstream);
size_t TO = infstream.total_out;
std::string Ret(TO, 0);
std::copy_n(C.begin(), TO, Ret.begin());
return Ret;
}
-244
View File
@@ -1,244 +0,0 @@
///
/// Created by Anonymous275 on 10/29/2020
///
#include "Lua/LuaSystem.hpp"
#ifdef WIN32
#include <conio.h>
#include <windows.h>
#else // *nix
typedef unsigned long DWORD, *PDWORD, *LPDWORD;
#include <termios.h>
#include <unistd.h>
#endif // WIN32
#include "Logger.h"
#include <array>
#include <cstring>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
std::vector<std::string> QConsoleOut;
std::string CInputBuff;
std::mutex MLock;
std::unique_ptr<Lua> LuaConsole;
void HandleInput(const std::string& cmd) {
std::cout << std::endl;
if (cmd == Sec("exit")) {
_Exit(0);
} else if (cmd == Sec("clear") || cmd == Sec("cls")) {
// 2J is clearscreen, H is reset position to top-left
ConsoleOut(Sec("\x1b[2J\x1b[H"));
} else {
LuaConsole->Execute(cmd);
}
}
void ProcessOut() {
static size_t len = 2;
if (QConsoleOut.empty() && len == CInputBuff.length())
return;
printf("%c[2K\r", 27);
for (const std::string& msg : QConsoleOut)
if (!msg.empty())
std::cout << msg;
MLock.lock();
QConsoleOut.clear();
MLock.unlock();
std::cout << "> " << CInputBuff << std::flush;
len = CInputBuff.length();
}
void ConsoleOut(const std::string& msg) {
MLock.lock();
QConsoleOut.emplace_back(msg);
MLock.unlock();
}
[[noreturn]] void OutputRefresh() {
DebugPrintTID();
while (true) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
ProcessOut();
}
}
#ifndef WIN32
static struct termios old, current;
void initTermios(int echo) {
tcgetattr(0, &old); /* grab old terminal i/o settings */
current = old; /* make new settings same as old settings */
current.c_lflag &= ~ICANON; /* disable buffered i/o */
if (echo) {
current.c_lflag |= ECHO; /* set echo mode */
} else {
current.c_lflag &= ~ECHO; /* set no echo mode */
}
tcsetattr(0, TCSANOW, &current); /* use these new terminal i/o settings now */
}
void resetTermios(void) {
tcsetattr(0, TCSANOW, &old);
}
char getch_(int echo) {
char ch;
initTermios(echo);
read(STDIN_FILENO, &ch, 1);
resetTermios();
return ch;
}
char _getch(void) {
return getch_(0);
}
#endif // WIN32
void SetupConsole() {
#if defined(WIN32)
DWORD outMode = 0;
HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (stdoutHandle == INVALID_HANDLE_VALUE) {
error("Invalid console handle! Inputs will not work properly");
return;
}
if (!GetConsoleMode(stdoutHandle, &outMode)) {
error("Invalid console mode! Inputs will not work properly");
return;
}
// Enable ANSI escape codes
outMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(stdoutHandle, outMode)) {
error("failed to set console mode! Inputs will not work properly");
return;
}
#else
#endif // WIN32
}
static std::vector<std::string> ConsoleHistory {};
static size_t ConsoleHistoryReadIndex { 0 };
static inline void ConsoleHistoryAdd(const std::string& cmd) {
ConsoleHistory.push_back(cmd);
ConsoleHistoryReadIndex = ConsoleHistory.size();
}
static std::string CompositeInput;
static bool CompositeInputExpected { false };
static void ProcessCompositeInput() {
#ifdef WIN32
if (CompositeInput.size() == 1 && memcmp(CompositeInput.data(), std::array<char, 1> { 72 }.data(), 1) == 0) {
#else // unix
if (CompositeInput.size() == 2 && memcmp(CompositeInput.data(), std::array<char, 2> { 91, 65 }.data(), 2) == 0) {
#endif // WIN32
// UP ARROW
// info(std::to_string(ConsoleHistoryReadIndex));
if (!ConsoleHistory.empty()) {
if (ConsoleHistoryReadIndex != 0) {
ConsoleHistoryReadIndex -= 1;
}
CInputBuff = ConsoleHistory.at(ConsoleHistoryReadIndex);
}
#ifdef WIN32
} else if (CompositeInput.size() == 1 && memcmp(CompositeInput.data(), std::array<char, 1> { 80 }.data(), 1) == 0) {
#else // unix
} else if (CompositeInput.size() == 2 && memcmp(CompositeInput.data(), std::array<char, 2> { 91, 66 }.data(), 2) == 0) {
#endif // WIN32
// DOWN ARROW
if (!ConsoleHistory.empty()) {
if (ConsoleHistoryReadIndex != ConsoleHistory.size() - 1) {
ConsoleHistoryReadIndex += 1;
CInputBuff = ConsoleHistory.at(ConsoleHistoryReadIndex);
} else {
CInputBuff = "";
ConsoleHistoryReadIndex = ConsoleHistory.size();
}
}
} else {
// not composite input, we made a mistake, so lets just add it to the buffer like usual
CInputBuff += CompositeInput;
}
// ensure history doesnt grow too far beyond a max
static constexpr size_t MaxHistory = 10;
if (ConsoleHistory.size() > 2 * MaxHistory) {
std::vector<std::string> NewHistory(ConsoleHistory.begin() + ConsoleHistory.size() - MaxHistory, ConsoleHistory.end());
ConsoleHistory = std::move(NewHistory);
ConsoleHistoryReadIndex = ConsoleHistory.size();
}
}
void ReadCin() {
DebugPrintTID();
size_t null_byte_counter = 0;
while (true) {
int In = _getch();
//info(std::to_string(In));
if (In == 0) {
++null_byte_counter;
if (null_byte_counter > 50) {
info(Sec("too many null bytes in input, this is now assumed to be a background thread - console input is now disabled"));
break;
}
}
if (CompositeInputExpected) {
CompositeInput += char(In);
#ifdef WIN32
if (CompositeInput.size() == 1) {
#else // unix
if (CompositeInput.size() == 2) {
#endif // WIN32
CompositeInputExpected = false;
ProcessCompositeInput();
}
continue;
}
if (In == 13 || In == '\n') {
if (!CInputBuff.empty()) {
HandleInput(CInputBuff);
ConsoleHistoryAdd(CInputBuff);
CInputBuff.clear();
}
} else if (In == 8 || In == 127) {
if (!CInputBuff.empty())
CInputBuff.pop_back();
} else if (In == 4) {
CInputBuff = "exit";
HandleInput(CInputBuff);
CInputBuff.clear();
} else if (In == 12) {
CInputBuff = "clear";
HandleInput(CInputBuff);
CInputBuff.clear();
#ifdef WIN32
} else if (In == 224) {
#else // unix
} else if (In == 27) {
#endif // WIN32
// escape char, assume stuff follows
CompositeInputExpected = true;
CompositeInput.clear();
} else if (!isprint(In)) {
// ignore
} else {
CInputBuff += char(In);
}
}
}
void ConsoleInit() {
SetupConsole();
LuaConsole = std::make_unique<Lua>(true);
LuaConsole->Init();
printf("> ");
std::thread In(ReadCin);
In.detach();
std::thread Out(OutputRefresh);
Out.detach();
}
-132
View File
@@ -1,132 +0,0 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "Security/Enc.h"
#include "CustomAssert.h"
#include "Settings.h"
//#include <windows.h>
#include "Logger.h"
#include <random>
#include <sstream>
#include <thread>
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);
}
#ifdef WIN32
int Handle(EXCEPTION_POINTERS* ep, char* Origin) {
//Assert(false);
std::stringstream R;
R << Sec("Code : ") << std::hex
<< ep->ExceptionRecord->ExceptionCode
<< std::dec << Sec(" Origin : ") << Origin;
except(R.str());
return 1;
}
#else
// stub
int Handle(EXCEPTION_POINTERS*, char*) { return 1; }
#endif // WIN32
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_E(const std::string& Data, int e, int n) {
std::stringstream stream;
for (const char& c : Data) {
stream << std::hex << Enc(uint8_t(c), e, 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;
}
-161
View File
@@ -1,161 +0,0 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "CustomAssert.h"
#include "Logger.h"
#include "Security/Enc.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 FoundTrue = std::string(Data).find("true") != std::string::npos; //searches for "true"
switch (Index) {
case 1:
Debug = FoundTrue; //checks and sets the Debug Value
break;
case 2:
Private = FoundTrue; //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) {
Assert(IFS.is_open());
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 = true # 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();
error(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();
}
-85
View File
@@ -1,85 +0,0 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "Client.hpp"
#include "Curl/Http.h"
#include "Logger.h"
#include "Security/Enc.h"
#include "Settings.h"
#include <chrono>
#include <future>
#include <sstream>
#include <thread>
void WebsocketInit();
std::string GetPlayers() {
std::string Return;
for (auto& c : CI->Clients) {
if (c != nullptr) {
Return += c->GetName() + ";";
}
}
return Return;
}
std::string GenerateCall() {
std::stringstream Ret;
Ret << "uuid=" << Key << "&players=" << CI->Size()
<< "&maxplayers=" << MaxPlayers << "&port=" << Port
<< "&map=" << MapName << "&private=" << (Private ? "true" : "false")
<< "&version=" << GetSVer() << "&clientversion=" << GetCVer()
<< "&name=" << ServerName << "&pps=" << StatReport
<< "&modlist=" << FileList << "&modstotalsize=" << MaxModSize
<< "&modstotal=" << ModsLoaded << "&playerslist=" << GetPlayers()
<< "&desc=" << ServerDesc;
return Ret.str();
}
std::string RunPromise(const std::string& IP, const std::string& R) {
std::packaged_task<std::string()> task([&] { return PostHTTP(IP, R); });
std::future<std::string> f1 = task.get_future();
std::thread t(std::move(task));
t.detach();
auto status = f1.wait_for(std::chrono::seconds(10));
if (status != std::future_status::timeout)
return f1.get();
error(Sec("Backend system Timeout please try again later"));
std::this_thread::sleep_for(std::chrono::seconds(3));
_Exit(0);
}
void Heartbeat() {
DebugPrintTID();
std::string R, T;
bool isAuth = false;
while (true) {
R = GenerateCall();
if (!CustomIP.empty())
R += "&ip=" + CustomIP;
std::string link = Sec("https://beammp.com/heartbeatv2");
T = RunPromise(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));
std::string Backup = Sec("https://backup1.beammp.com/heartbeatv2");
T = RunPromise(Backup, 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();
if (!isAuth) {
WebsocketInit();
isAuth = true;
}
std::this_thread::sleep_for(std::chrono::seconds(3));
}
}
void HBInit() {
std::thread HB(Heartbeat);
HB.detach();
}
-36
View File
@@ -1,36 +0,0 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "Logger.h"
#include "Security/Enc.h"
#include "Settings.h"
#include <algorithm>
#include <filesystem>
namespace fs = std::filesystem;
uint64_t MaxModSize = 0;
std::string FileSizes;
std::string FileList;
int ModsLoaded = 0;
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() + ";";
FileSizes += std::to_string(fs::file_size(entry.path())) + ";";
MaxModSize += fs::file_size(entry.path());
ModsLoaded++;
}
}
}
std::replace(FileList.begin(), FileList.end(), '\\', '/');
if (ModsLoaded) {
info(Sec("Loaded ") + std::to_string(ModsLoaded) + Sec(" Mods"));
}
}
-34
View File
@@ -1,34 +0,0 @@
///
/// Created by Anonymous275 on 7/28/2020
///
#include "Client.hpp"
#include "Logger.h"
#include "Security/Enc.h"
#include <algorithm>
#include <string>
std::string CustomIP;
std::string GetSVer() {
return std::string(Sec("1.13"));
}
std::string GetCVer() {
return std::string(Sec("1.70"));
}
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 = std::make_unique<ClientInterface>();
}
-88
View File
@@ -1,88 +0,0 @@
///
/// Created by Anonymous275 on 5/20/2020
///
#include "Logger.h"
#include "Lua/LuaSystem.hpp"
#include "Security/Enc.h"
#include "Settings.h"
#include <thread>
#ifdef __linux
// we need this for `struct stat`
#include <sys/stat.h>
#endif // __linux
std::set<std::unique_ptr<Lua>> PluginEngine;
bool NewFile(const std::string& Path) {
for (auto& Script : PluginEngine) {
if (Path == Script->GetFileName())
return false;
}
return true;
}
void RegisterFiles(const std::string& Path, bool HotSwap) {
std::string Name = Path.substr(Path.find_last_of('\\') + 1);
if (!HotSwap)
info(Sec("Loading plugin : ") + Name);
for (const auto& entry : fs::directory_iterator(Path)) {
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())) {
auto FileName = entry.path().string();
std::unique_ptr<Lua> ScriptToInsert(new Lua(Name, FileName, fs::last_write_time(FileName)));
auto& Script = *ScriptToInsert;
PluginEngine.insert(std::move(ScriptToInsert));
Script.Init();
if (HotSwap)
info(Sec("[HOTSWAP] Added : ") + Script.GetFileName().substr(Script.GetFileName().find('\\')));
}
}
}
}
void FolderList(const std::string& Path, bool HotSwap) {
for (const auto& entry : fs::directory_iterator(Path)) {
auto pos = entry.path().filename().string().find('.');
if (pos == std::string::npos) {
RegisterFiles(entry.path().string(), HotSwap);
}
}
}
[[noreturn]] void HotSwaps(const std::string& path) {
DebugPrintTID();
while (true) {
if (!PluginEngine.empty()) {
for (auto& Script : PluginEngine) {
struct stat Info { };
if (stat(Script->GetFileName().c_str(), &Info) != 0) {
Script->SetStopThread(true);
PluginEngine.erase(Script);
info(Sec("[HOTSWAP] Removed removed script due to delete"));
break;
}
if (Script->GetLastWrite() != fs::last_write_time(Script->GetFileName())) {
Script->SetStopThread(true);
info(Sec("[HOTSWAP] Updated Scripts due to edit"));
Script->SetLastWrite(fs::last_write_time(Script->GetFileName()));
Script->Reload();
}
}
}
FolderList(path, true);
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
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(Sec("Lua system online"));
}
-668
View File
@@ -1,668 +0,0 @@
///
/// Created by Anonymous275 on 5/19/2020
///
#include "Lua/LuaSystem.hpp"
#include "Client.hpp"
#include "Logger.h"
#include "Network.h"
#include "Security/Enc.h"
#include "Settings.h"
#include "UnixCompat.h"
#include <future>
#include <iostream>
#include <optional>
#include <utility>
std::shared_ptr<LuaArg> CreateArg(lua_State* L, int T, int S) {
if (S > T)
return nullptr;
std::shared_ptr<LuaArg> 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)) {
temp->args.emplace_back(int(lua_tointeger(L, C)));
} else if (lua_isboolean(L, C)) {
temp->args.emplace_back(bool(lua_toboolean(L, C)));
} else if (lua_isnumber(L, C)) {
temp->args.emplace_back(float(lua_tonumber(L, C)));
}
}
return temp;
}
void ClearStack(lua_State* L) {
lua_settop(L, 0);
}
std::optional<std::reference_wrapper<Lua>> GetScript(lua_State* L) {
for (auto& Script : PluginEngine) {
if (Script->GetState() == L)
return *Script;
}
return std::nullopt;
}
void SendError(lua_State* L, const std::string& msg) {
Assert(L);
auto MaybeS = GetScript(L);
std::string a;
if (!MaybeS.has_value()) {
a = Sec("_Console");
} else {
Lua& S = MaybeS.value();
a = fs::path(S.GetFileName()).filename().string();
}
warn(a + Sec(" | Incorrect Call of ") + msg);
}
int Trigger(Lua* lua, const std::string& R, std::shared_ptr<LuaArg> arg) {
std::lock_guard<std::mutex> lockGuard(lua->Lock);
std::packaged_task<int(std::shared_ptr<LuaArg>)> task([lua, R](std::shared_ptr<LuaArg> arg) { return CallFunction(lua, R, arg); });
std::future<int> f1 = task.get_future();
std::thread t(std::move(task), arg);
t.detach();
auto status = f1.wait_for(std::chrono::seconds(5));
if (status != std::future_status::timeout)
return f1.get();
SendError(lua->GetState(), R + " took too long to respond");
return 0;
}
int FutureWait(Lua* lua, const std::string& R, std::shared_ptr<LuaArg> arg, bool Wait) {
Assert(lua);
std::packaged_task<int(std::shared_ptr<LuaArg>)> task([lua, R](std::shared_ptr<LuaArg> arg) { return Trigger(lua, R, arg); });
std::future<int> f1 = task.get_future();
std::thread t(std::move(task), arg);
t.detach();
int T = 0;
if (Wait)
T = 6;
auto status = f1.wait_for(std::chrono::seconds(T));
if (status != std::future_status::timeout)
return f1.get();
return 0;
}
int TriggerLuaEvent(const std::string& Event, bool local, Lua* Caller, std::shared_ptr<LuaArg> arg, bool Wait) {
int R = 0;
for (auto& Script : PluginEngine) {
if (Script->IsRegistered(Event)) {
if (local) {
if (Script->GetPluginName() == Caller->GetPluginName()) {
R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
}
} else
R += FutureWait(Script.get(), Script->GetRegistered(Event), arg, Wait);
}
}
return R;
}
bool ConsoleCheck(lua_State* L, int r) {
if (r != LUA_OK) {
std::string msg = lua_tostring(L, -1);
warn(Sec("_Console | ") + msg);
return false;
}
return true;
}
bool CheckLua(lua_State* L, int r) {
if (r != LUA_OK) {
std::string msg = lua_tostring(L, -1);
auto MaybeS = GetScript(L);
if (MaybeS.has_value()) {
Lua& S = MaybeS.value();
std::string a = fs::path(S.GetFileName()).filename().string();
warn(a + " | " + msg);
return false;
}
// What the fuck, what do we do?!
AssertNotReachable();
}
return true;
}
int lua_RegisterEvent(lua_State* L) {
int Args = lua_gettop(L);
auto MaybeScript = GetScript(L);
Assert(MaybeScript.has_value());
Lua& Script = MaybeScript.value();
if (Args == 2 && lua_isstring(L, 1) && lua_isstring(L, 2)) {
Script.RegisterEvent(lua_tostring(L, 1), lua_tostring(L, 2));
} else
SendError(L, Sec("RegisterEvent invalid argument count expected 2 got ") + std::to_string(Args));
return 0;
}
int lua_TriggerEventL(lua_State* L) {
int Args = lua_gettop(L);
auto MaybeScript = GetScript(L);
Assert(MaybeScript.has_value());
Lua& Script = MaybeScript.value();
if (Args > 0) {
if (lua_isstring(L, 1)) {
TriggerLuaEvent(lua_tostring(L, 1), true, &Script, CreateArg(L, Args, 2), false);
} else
SendError(L, Sec("TriggerLocalEvent wrong argument [1] need string"));
} else {
SendError(L, Sec("TriggerLocalEvent not enough arguments expected 1 got 0"));
}
return 0;
}
int lua_TriggerEventG(lua_State* L) {
int Args = lua_gettop(L);
auto MaybeScript = GetScript(L);
Assert(MaybeScript.has_value());
Lua& Script = MaybeScript.value();
if (Args > 0) {
if (lua_isstring(L, 1)) {
TriggerLuaEvent(lua_tostring(L, 1), false, &Script, CreateArg(L, Args, 2), false);
} else
SendError(L, Sec("TriggerGlobalEvent wrong argument [1] need string"));
} else
SendError(L, Sec("TriggerGlobalEvent not enough arguments"));
return 0;
}
char* ThreadOrigin(Lua* lua) {
std::string T = "Thread in " + fs::path(lua->GetFileName()).filename().string();
char* Data = new char[T.size() + 1];
ZeroMemory(Data, T.size() + 1);
memcpy(Data, T.c_str(), T.size());
return Data;
}
void SafeExecution(Lua* lua, const std::string& FuncName) {
lua_State* luaState = lua->GetState();
lua_getglobal(luaState, FuncName.c_str());
if (lua_isfunction(luaState, -1)) {
char* Origin = ThreadOrigin(lua);
#ifdef WIN32
__try {
int R = lua_pcall(luaState, 0, 0, 0);
CheckLua(luaState, R);
} __except (Handle(GetExceptionInformation(), Origin)) {
}
#else // unix
int R = lua_pcall(luaState, 0, 0, 0);
CheckLua(luaState, R);
#endif // WIN32
delete[] Origin;
}
ClearStack(luaState);
}
void ExecuteAsync(Lua* lua, const std::string& FuncName) {
std::lock_guard<std::mutex> lockGuard(lua->Lock);
SafeExecution(lua, FuncName);
}
void CallAsync(Lua* lua, const std::string& Func, int U) {
DebugPrintTID();
lua->SetStopThread(false);
int D = 1000 / U;
while (!lua->GetStopThread()) {
ExecuteAsync(lua, Func);
std::this_thread::sleep_for(std::chrono::milliseconds(D));
}
}
int lua_StopThread(lua_State* L) {
auto MaybeScript = GetScript(L);
Assert(MaybeScript.has_value());
// ugly, but whatever, this is safe as fuck
MaybeScript.value().get().SetStopThread(true);
return 0;
}
int lua_CreateThread(lua_State* L) {
int Args = lua_gettop(L);
if (Args > 1) {
if (lua_isstring(L, 1)) {
std::string STR = lua_tostring(L, 1);
if (lua_isinteger(L, 2) || lua_isnumber(L, 2)) {
int U = int(lua_tointeger(L, 2));
if (U > 0 && U < 501) {
auto MaybeScript = GetScript(L);
Assert(MaybeScript.has_value());
Lua& Script = MaybeScript.value();
std::thread t1(CallAsync, &Script, STR, U);
t1.detach();
} 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 = int(lua_tonumber(L, 1));
std::this_thread::sleep_for(std::chrono::milliseconds(t));
} else {
SendError(L, Sec("Sleep not enough arguments"));
return 0;
}
return 1;
}
Client* GetClient(int ID) {
for (auto& c : CI->Clients) {
if (c != nullptr && c->GetID() == ID) {
return c.get();
}
}
return nullptr;
}
int lua_isConnected(lua_State* L) {
if (lua_isnumber(L, 1)) {
int ID = int(lua_tonumber(L, 1));
Client* c = GetClient(ID);
if (c != nullptr)
lua_pushboolean(L, c->isConnected);
else
return 0;
} else {
SendError(L, Sec("isConnected not enough arguments"));
return 0;
}
return 1;
}
int lua_GetPlayerName(lua_State* L) {
if (lua_isnumber(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, Sec("GetPlayerName not enough arguments"));
return 0;
}
return 1;
}
int lua_GetPlayerCount(lua_State* L) {
lua_pushinteger(L, CI->Size());
return 1;
}
int lua_GetDID(lua_State* L) {
if (lua_isnumber(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, Sec("GetDID not enough arguments"));
return 0;
}
return 1;
}
int lua_GetAllPlayers(lua_State* L) {
lua_newtable(L);
int i = 1;
for (auto& 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 (CI->Clients.empty())
return 0;
return 1;
}
int lua_GetCars(lua_State* L) {
if (lua_isnumber(L, 1)) {
int ID = int(lua_tonumber(L, 1));
Client* c = GetClient(ID);
if (c != nullptr) {
int i = 1;
for (auto& 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, Sec("GetPlayerVehicles not enough arguments"));
return 0;
}
return 1;
}
int lua_dropPlayer(lua_State* L) {
int Args = lua_gettop(L);
if (lua_isnumber(L, 1)) {
int ID = int(lua_tonumber(L, 1));
Client* c = GetClient(ID);
if (c == nullptr)
return 0;
if (c->GetRole() == Sec("MDEV"))
return 0;
std::string Reason;
if (Args > 1 && lua_isstring(L, 2)) {
Reason = std::string(Sec(" Reason : ")) + lua_tostring(L, 2);
}
Respond(c, "C:Server:You have been Kicked from the server! " + Reason, true);
c->SetStatus(-2);
info(Sec("Closing socket due to kick"));
CloseSocketProper(c->GetTCPSock());
} else
SendError(L, Sec("DropPlayer not enough arguments"));
return 0;
}
int lua_sendChat(lua_State* L) {
if (lua_isinteger(L, 1) || lua_isnumber(L, 1)) {
if (lua_isstring(L, 2)) {
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) {
if (!c->isSynced)
return 0;
std::string Packet = "C:Server: " + std::string(lua_tostring(L, 2));
Respond(c, Packet, true);
} else
SendError(L, Sec("SendChatMessage invalid argument [1] invalid ID"));
}
} 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, 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 = int(lua_tointeger(L, 1));
int VID = int(lua_tointeger(L, 2));
Client* c = GetClient(PID);
if (c == nullptr) {
SendError(L, Sec("RemoveVehicle invalid Player ID"));
return 0;
}
if (c->GetRole() == "MDEV")
return 0;
if (!c->GetCarData(VID).empty()) {
std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID);
SendToAll(nullptr, Destroy, true, true);
c->DeleteCar(VID);
}
} else
SendError(L, Sec("RemoveVehicle invalid argument expected number"));
return 0;
}
int lua_HWID(lua_State* L) {
lua_pushinteger(L, -1);
return 1;
}
int lua_RemoteEvent(lua_State* L) {
int Args = lua_gettop(L);
if (Args != 3) {
SendError(L, Sec("TriggerClientEvent invalid argument count expected 3 got ") + std::to_string(Args));
return 0;
}
if (!lua_isnumber(L, 1)) {
SendError(L, Sec("TriggerClientEvent invalid argument [1] expected number"));
return 0;
}
if (!lua_isstring(L, 2)) {
SendError(L, Sec("TriggerClientEvent invalid argument [2] expected string"));
return 0;
}
if (!lua_isstring(L, 3)) {
SendError(L, Sec("TriggerClientEvent invalid argument [3] expected string"));
return 0;
}
int ID = int(lua_tointeger(L, 1));
std::string Packet = "E:" + std::string(lua_tostring(L, 2)) + ":" + std::string(lua_tostring(L, 3));
if (ID == -1)
SendToAll(nullptr, Packet, true, true);
else {
Client* c = GetClient(ID);
if (c == nullptr) {
SendError(L, Sec("TriggerClientEvent invalid Player ID"));
return 0;
}
Respond(c, Packet, true);
}
return 0;
}
int lua_ServerExit(lua_State*) {
_Exit(0);
}
int lua_Set(lua_State* L) {
int Args = lua_gettop(L);
if (Args != 2) {
SendError(L, Sec("set invalid argument count expected 2 got ") + std::to_string(Args));
return 0;
}
if (!lua_isnumber(L, 1)) {
SendError(L, Sec("set invalid argument [1] expected number"));
return 0;
}
auto MaybeSrc = GetScript(L);
std::string Name;
if (!MaybeSrc.has_value()) {
Name = Sec("_Console");
} else {
Name = MaybeSrc.value().get().GetPluginName();
}
int C = int(lua_tointeger(L, 1));
switch (C) {
case 0: //debug
if (lua_isboolean(L, 2)) {
Debug = lua_toboolean(L, 2);
info(Name + Sec(" | Debug -> ") + (Debug ? "true" : "false"));
} else
SendError(L, Sec("set invalid argument [2] expected boolean for ID : 0"));
break;
case 1: //private
if (lua_isboolean(L, 2)) {
Private = lua_toboolean(L, 2);
info(Name + Sec(" | Private -> ") + (Private ? "true" : "false"));
} else
SendError(L, Sec("set invalid argument [2] expected boolean for ID : 1"));
break;
case 2: //max cars
if (lua_isnumber(L, 2)) {
MaxCars = int(lua_tointeger(L, 2));
info(Name + Sec(" | MaxCars -> ") + std::to_string(MaxCars));
} else
SendError(L, Sec("set invalid argument [2] expected number for ID : 2"));
break;
case 3: //max players
if (lua_isnumber(L, 2)) {
MaxPlayers = int(lua_tointeger(L, 2));
info(Name + Sec(" | MaxPlayers -> ") + std::to_string(MaxPlayers));
} else
SendError(L, Sec("set invalid argument [2] expected number for ID : 3"));
break;
case 4: //Map
if (lua_isstring(L, 2)) {
MapName = lua_tostring(L, 2);
info(Name + Sec(" | MapName -> ") + MapName);
} else
SendError(L, Sec("set invalid argument [2] expected string for ID : 4"));
break;
case 5: //Name
if (lua_isstring(L, 2)) {
ServerName = lua_tostring(L, 2);
info(Name + Sec(" | ServerName -> ") + ServerName);
} else
SendError(L, Sec("set invalid argument [2] expected string for ID : 5"));
break;
case 6: //Desc
if (lua_isstring(L, 2)) {
ServerDesc = lua_tostring(L, 2);
info(Name + Sec(" | ServerDesc -> ") + ServerDesc);
} else
SendError(L, Sec("set invalid argument [2] expected string for ID : 6"));
break;
default:
warn(Sec("Invalid config ID : ") + std::to_string(C));
break;
}
return 0;
}
extern "C" {
int lua_Print(lua_State* L) {
int Arg = lua_gettop(L);
for (int i = 1; i <= Arg; i++) {
auto str = lua_tostring(L, i);
if (str != nullptr) {
ConsoleOut(str + std::string(Sec("\n")));
} else {
ConsoleOut(Sec("nil\n"));
}
}
return 0;
}
}
Lua::Lua(const std::string& PluginName, const std::string& FileName, fs::file_time_type LastWrote, bool Console)
: luaState(luaL_newstate()) {
Assert(luaState);
if (!PluginName.empty()) {
SetPluginName(PluginName);
}
if (!FileName.empty()) {
SetFileName(FileName);
}
SetLastWrite(LastWrote);
_Console = Console;
}
Lua::Lua(bool Console)
: luaState(luaL_newstate()) {
_Console = Console;
}
void Lua::Execute(const std::string& Command) {
if (ConsoleCheck(luaState, luaL_dostring(luaState, Command.c_str()))) {
lua_settop(luaState, 0);
}
}
void Lua::Reload() {
if (CheckLua(luaState, luaL_dofile(luaState, _FileName.c_str()))) {
CallFunction(this, Sec("onInit"), nullptr);
}
}
std::string Lua::GetOrigin() {
return fs::path(GetFileName()).filename().string();
}
int CallFunction(Lua* lua, const std::string& FuncName, std::shared_ptr<LuaArg> Arg) {
lua_State* luaState = lua->GetState();
lua_getglobal(luaState, FuncName.c_str());
if (lua_isfunction(luaState, -1)) {
int Size = 0;
if (Arg != nullptr) {
Size = int(Arg->args.size());
Arg->PushArgs(luaState);
}
std::string Origin = lua->GetOrigin();
int R = lua_pcall(luaState, Size, 1, 0);
if (CheckLua(luaState, R)) {
if (lua_isnumber(luaState, -1)) {
return int(lua_tointeger(luaState, -1));
}
}
}
ClearStack(luaState);
return 0;
}
void Lua::SetPluginName(const std::string& Name) {
_PluginName = Name;
}
void Lua::SetFileName(const std::string& Name) {
_FileName = Name;
}
void Lua::Init() {
Assert(luaState);
luaL_openlibs(luaState);
lua_register(luaState, "TriggerGlobalEvent", lua_TriggerEventG);
lua_register(luaState, "TriggerLocalEvent", lua_TriggerEventL);
lua_register(luaState, "TriggerClientEvent", lua_RemoteEvent);
lua_register(luaState, "GetPlayerCount", lua_GetPlayerCount);
lua_register(luaState, "isPlayerConnected", lua_isConnected);
lua_register(luaState, "RegisterEvent", lua_RegisterEvent);
lua_register(luaState, "GetPlayerName", lua_GetPlayerName);
lua_register(luaState, "RemoveVehicle", lua_RemoveVehicle);
lua_register(luaState, "GetPlayerDiscordID", lua_GetDID);
lua_register(luaState, "GetPlayerVehicles", lua_GetCars);
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, "exit", lua_ServerExit);
lua_register(luaState, "Sleep", lua_Sleep);
lua_register(luaState, "print", lua_Print);
lua_register(luaState, "Set", lua_Set);
if (!_Console)
Reload();
}
void Lua::RegisterEvent(const std::string& Event, const std::string& FunctionName) {
_RegisteredEvents.insert(std::make_pair(Event, FunctionName));
}
void Lua::UnRegisterEvent(const std::string& Event) {
for (const std::pair<std::string, std::string>& a : _RegisteredEvents) {
if (a.first == Event) {
_RegisteredEvents.erase(a);
break;
}
}
}
bool Lua::IsRegistered(const std::string& Event) {
for (const std::pair<std::string, std::string>& a : _RegisteredEvents) {
if (a.first == Event)
return true;
}
return false;
}
std::string Lua::GetRegistered(const std::string& Event) const {
for (const std::pair<std::string, std::string>& a : _RegisteredEvents) {
if (a.first == Event)
return a.second;
}
return "";
}
std::string Lua::GetFileName() const {
return _FileName;
}
std::string Lua::GetPluginName() const {
return _PluginName;
}
lua_State* Lua::GetState() {
return luaState;
}
const lua_State* Lua::GetState() const {
return luaState;
}
void Lua::SetLastWrite(fs::file_time_type time) {
_LastWrote = time;
}
fs::file_time_type Lua::GetLastWrite() {
return _LastWrote;
}
Lua::~Lua() {
info("closing lua state");
lua_close(luaState);
}
-318
View File
@@ -1,318 +0,0 @@
///
/// Created by Anonymous275 on 7/31/2020
///
#include "Curl/Http.h"
#include "Logger.h"
#include "Network.h"
#include "Security/Enc.h"
#include "Settings.h"
#include "UnixCompat.h"
#include <algorithm>
#include <atomic>
#include <cstring>
#include <sstream>
#include <string>
#include <thread>
bool Send(SOCKET TCPSock, std::string Data) {
#ifdef WIN32
int BytesSent;
int len = static_cast<int>(Data.size());
#else
int64_t BytesSent;
size_t len = Data.size();
#endif // WIN32
BytesSent = send(TCPSock, Data.c_str(), len, 0);
Data.clear();
if (BytesSent <= 0) {
#ifndef WIN32
error(__func__ + std::string(" ") + strerror(errno));
#else
error(__func__ + std::string(" ") + std::to_string(WSAGetLastError()));
#endif // WIN32
return false;
}
return true;
}
std::string Rcv(SOCKET TCPSock) {
uint32_t RealSize;
#ifdef WIN32
int64_t BytesRcv = recv(TCPSock, reinterpret_cast<char*>(&RealSize), sizeof(RealSize), 0);
#else
int64_t BytesRcv = recv(TCPSock, reinterpret_cast<void*>(&RealSize), sizeof(RealSize), 0);
#endif
if (BytesRcv != sizeof(RealSize)) {
error(std::string(Sec("invalid packet: expected 4, got ")) + std::to_string(BytesRcv));
return "";
}
// RealSize is big-endian, so we convert it to host endianness
RealSize = ntohl(RealSize);
debug(std::string("got ") + std::to_string(RealSize) + " as size");
if (RealSize > 7000) {
error(Sec("Larger than allowed TCP packet received"));
return "";
}
char buf[7000];
std::fill_n(buf, 7000, 0);
BytesRcv = recv(TCPSock, buf, RealSize, 0);
if (BytesRcv != RealSize) {
debug("expected " + std::to_string(RealSize) + " bytes, got " + std::to_string(BytesRcv) + " instead");
}
if (BytesRcv <= 0)
return "";
return std::string(buf);
}
std::string GetRole(const std::string& DID) {
if (!DID.empty()) {
std::string a = HttpRequest(Sec("https://beammp.com/entitlement?did=") + DID, 443);
std::string b = HttpRequest(Sec("https://backup1.beammp.com/entitlement?did=") + DID, 443);
if (!a.empty() || !b.empty()) {
if (a != b)
a = b;
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(SOCKET TCPSock, std::shared_ptr<std::atomic_bool> ok) {
DebugPrintTID();
size_t accum = 0;
while (!*ok) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
accum += 100;
if (accum >= 5000) {
error(Sec("Identification timed out (Check accum)"));
CloseSocketProper(TCPSock);
return;
}
}
}
int Max() {
int M = MaxPlayers;
for (auto& 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);
Client& Client = *c;
CI->AddClient(std::move(c));
InitClient(&Client);
}
std::pair<int, int> Parse(const std::string& msg) {
std::stringstream ss(msg);
std::string t;
std::pair<int, int> a = { 0, 0 }; //N then E
while (std::getline(ss, t, 'g')) {
if (t.find_first_not_of(Sec("0123456789abcdef")) != std::string::npos)
return a;
if (a.first == 0) {
a.first = std::stoi(t, nullptr, 16);
} else if (a.second == 0) {
a.second = std::stoi(t, nullptr, 16);
} else
return a;
}
return { 0, 0 };
}
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, RSA* Skey) {
DebugPrintTID();
Assert(Skey);
std::shared_ptr<std::atomic_bool> ok = std::make_shared<std::atomic_bool>(false);
std::thread Timeout(Check, TCPSock, ok);
Timeout.detach();
std::string Name, DID, Role;
if (!Send(TCPSock, GenerateM(Skey))) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
return;
}
std::string msg = Rcv(TCPSock);
auto Keys = Parse(msg);
if (!Send(TCPSock, RSA_E("HC", Keys.second, Keys.first))) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
return;
}
std::string Res = Rcv(TCPSock);
std::string Ver = Rcv(TCPSock);
*ok = true;
Ver = RSA_D(Ver, Skey);
if (Ver.size() > 3 && Ver.substr(0, 2) == Sec("VC")) {
Ver = Ver.substr(2);
if (Ver.length() > 4 || Ver != GetCVer()) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
return;
}
} else {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
return;
}
Res = RSA_D(Res, Skey);
if (Res.size() < 3 || Res.substr(0, 2) != Sec("NR")) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
return;
}
if (Res.find(':') == std::string::npos) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(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")) != std::string::npos) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
return;
}
// DebugPrintTIDInternal(std::string("Client(") + Name + ")");
debug(Sec("Name -> ") + Name + Sec(", Role -> ") + Role + Sec(", ID -> ") + DID);
for (auto& c : CI->Clients) {
if (c != nullptr) {
if (c->GetDID() == DID) {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(c->GetTCPSock());
c->SetStatus(-2);
break;
}
}
}
if (Role == Sec("MDEV") || CI->Size() < Max()) {
debug("Identification success");
CreateClient(TCPSock, Name, DID, Role);
} else {
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
}
}
void Identify(SOCKET TCPSock) {
RSA* Skey = GenKey();
// this disgusting ifdef stuff is needed because for some
// reason MSVC defines __try and __except and libg++ defines
// __try and __catch so its all a big mess if we leave this in or undefine
// the macros
/*#ifdef WIN32
__try{
#endif // WIN32*/
Identification(TCPSock, Skey);
/*#ifdef WIN32
}__except(1){
if(TCPSock != -1){
error("died on " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(TCPSock);
}
}
#endif // WIN32*/
delete Skey;
}
void TCPServerMain() {
DebugPrintTID();
#ifdef WIN32
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 {
try {
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();
} catch (const std::exception& e) {
error(Sec("fatal: ") + std::string(e.what()));
}
} while (client);
CloseSocketProper(client);
WSACleanup();
#else // unix
// wondering why we need slightly different implementations of this?
// ask ms.
SOCKET client = -1, Listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int optval = 1;
setsockopt(Listener, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
// TODO: check optval or return value idk
sockaddr_in addr {};
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = htons(uint16_t(Port));
if (bind(Listener, (sockaddr*)&addr, sizeof(addr)) != 0) {
error(Sec("Can't bind socket! ") + std::string(strerror(errno)));
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::string(strerror(errno)));
return;
}
info(Sec("Vehicle event network online"));
do {
try {
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();
} catch (const std::exception& e) {
error(Sec("fatal: ") + std::string(e.what()));
}
} while (client);
debug("all ok, arrived at " + std::string(__func__) + ":" + std::to_string(__LINE__));
CloseSocketProper(client);
#endif // WIN32
}
-105
View File
@@ -1,105 +0,0 @@
///
/// Created by Anonymous275 on 5/8/2020
///
#include "Client.hpp"
std::string Client::GetName() {
return Name;
}
void Client::SetName(const std::string& name) {
Name = name;
}
void Client::SetDID(const std::string& did) {
DID = did;
}
std::string Client::GetDID() {
return DID;
}
void Client::SetRole(const std::string& role) {
Role = role;
}
std::string Client::GetRole() {
return Role;
}
int Client::GetID() {
return ID;
}
void Client::SetID(int id) {
ID = id;
}
void Client::SetStatus(int state) {
Status = state;
}
int Client::GetStatus() {
return Status;
}
void Client::SetUDPAddr(sockaddr_in Addr) {
UDPADDR = Addr;
}
sockaddr_in Client::GetUDPAddr() {
return UDPADDR;
}
void Client::SetTCPSock(SOCKET CSock) {
TCPSOCK = CSock;
}
SOCKET Client::GetTCPSock() {
return TCPSOCK;
}
void Client::DeleteCar(int ident) {
for (auto& v : VehicleData) {
if (v != nullptr && v->ID == ident) {
VehicleData.erase(v);
break;
}
}
}
void Client::ClearCars() {
VehicleData.clear();
}
int Client::GetOpenCarID() {
int OpenID = 0;
bool found;
do {
found = true;
for (auto& v : VehicleData) {
if (v != nullptr && v->ID == OpenID) {
OpenID++;
found = false;
}
}
} while (!found);
return OpenID;
}
void Client::AddNewCar(int ident, const std::string& Data) {
VehicleData.insert(std::unique_ptr<VData>(new VData { ident, Data }));
}
std::set<std::unique_ptr<VData>>& Client::GetAllCars() {
return VehicleData;
}
const std::set<std::unique_ptr<VData>>& Client::GetAllCars() const {
return VehicleData;
}
std::string Client::GetCarData(int ident) {
for (auto& v : VehicleData) {
if (v != nullptr && v->ID == ident) {
return v->Data;
}
}
DeleteCar(ident);
return "";
}
void Client::SetCarData(int ident, const std::string& Data) {
for (auto& v : VehicleData) {
if (v != nullptr && v->ID == ident) {
v->Data = Data;
return;
}
}
DeleteCar(ident);
}
int Client::GetCarCount() {
return int(VehicleData.size());
}
-254
View File
@@ -1,254 +0,0 @@
///
/// Created by Anonymous275 on 8/1/2020
///
#include "Client.hpp"
#include "Logger.h"
#include "Lua/LuaSystem.hpp"
#include "Network.h"
#include "Security/Enc.h"
#include "Settings.h"
#include "UnixCompat.h"
#include <memory>
#include <sstream>
int FC(const std::string& s, const std::string& p, int n) {
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 int(i);
else
return -1;
}
void Apply(Client* c, int VID, const std::string& pckt) {
Assert(c);
std::string Packet = pckt;
std::string VD = c->GetCarData(VID);
Packet = Packet.substr(FC(Packet, ",", 2) + 1);
Packet = VD.substr(0, FC(VD, ",", 2) + 1) + Packet.substr(0, Packet.find_last_of('"') + 1) + VD.substr(FC(VD, ",\"", 7));
c->SetCarData(VID, Packet);
}
void VehicleParser(Client* c, const std::string& Pckt) {
Assert(c);
if (c == nullptr || Pckt.length() < 4)
return;
std::string Packet = Pckt;
char Code = Packet.at(1);
int PID = -1;
int VID = -1;
std::string Data = Packet.substr(3), pid, vid;
switch (Code) { //Spawned Destroyed Switched/Moved NotFound Reset
case 's':
#ifdef DEBUG
debug(std::string(Sec("got 'Os' packet: '")) + Packet + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
if (Data.at(0) == '0') {
int CarID = c->GetOpenCarID();
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(Sec("onVehicleSpawn"), false, nullptr, std::make_unique<LuaArg>(LuaArg { { c->GetID(), CarID, Packet.substr(3) } }), true)) {
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);
}
}
return;
case 'c':
#ifdef DEBUG
debug(std::string(Sec("got 'Oc' packet: '")) + Packet + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
pid = Data.substr(0, Data.find('-'));
vid = Data.substr(Data.find('-') + 1, Data.find(':', 1) - Data.find('-') - 1);
if (pid.find_first_not_of("0123456789") == std::string::npos && vid.find_first_not_of("0123456789") == std::string::npos) {
PID = stoi(pid);
VID = stoi(vid);
}
if (PID != -1 && VID != -1 && PID == c->GetID()) {
if (!TriggerLuaEvent(Sec("onVehicleEdited"), false, nullptr,
std::unique_ptr<LuaArg>(new LuaArg { { c->GetID(), VID, Packet.substr(3) } }),
true)) {
SendToAll(c, Packet, false, true);
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);
}
}
return;
case 'd':
#ifdef DEBUG
debug(std::string(Sec("got 'Od' packet: '")) + Packet + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
pid = Data.substr(0, Data.find('-'));
vid = Data.substr(Data.find('-') + 1);
if (pid.find_first_not_of("0123456789") == std::string::npos && vid.find_first_not_of("0123456789") == std::string::npos) {
PID = stoi(pid);
VID = stoi(vid);
}
if (PID != -1 && VID != -1 && PID == c->GetID()) {
SendToAll(nullptr, Packet, true, true);
TriggerLuaEvent(Sec("onVehicleDeleted"), false, nullptr,
std::unique_ptr<LuaArg>(new LuaArg { { c->GetID(), VID } }), false);
c->DeleteCar(VID);
debug(c->GetName() + Sec(" deleted car with ID ") + std::to_string(VID));
}
return;
case 'r':
#ifdef DEBUG
debug(std::string(Sec("got 'Or' packet: '")) + Packet + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
SendToAll(c, Packet, false, true);
return;
case 't':
#ifdef DEBUG
debug(std::string(Sec("got 'Ot' packet: '")) + Packet + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
SendToAll(c, Packet, false, true);
return;
default:
#ifdef DEBUG
warn(std::string(Sec("possibly not implemented: '") + Packet + Sec("' (") + std::to_string(Packet.size()) + Sec(")")));
#endif // DEBUG
return;
}
}
void SyncClient(Client* c) {
Assert(c);
if (c->isSynced)
return;
c->isSynced = true;
std::this_thread::sleep_for(std::chrono::seconds(1));
Respond(c, Sec("Sn") + c->GetName(), true);
SendToAll(c, Sec("JWelcome ") + c->GetName() + "!", false, true);
TriggerLuaEvent(Sec("onPlayerJoin"), false, nullptr, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID() } }), false);
for (auto& client : CI->Clients) {
if (client != nullptr) {
if (client.get() != c) {
for (auto& v : client->GetAllCars()) {
if (v != nullptr) {
if(c->GetStatus() < 0)return;
Respond(c, v->Data, true);
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
}
}
}
info(c->GetName() + Sec(" is now synced!"));
}
void ParseVeh(Client* c, const std::string& Packet) {
Assert(c);
#ifdef WIN32
__try {
VehicleParser(c, Packet);
} __except (Handle(GetExceptionInformation(), Sec("Vehicle Handler"))) { }
#else // unix
VehicleParser(c, Packet);
#endif // WIN32
}
void HandleEvent(Client* c, const std::string& Data) {
Assert(c);
std::stringstream ss(Data);
std::string t, Name;
int a = 0;
while (std::getline(ss, t, ':')) {
switch (a) {
case 1:
Name = t;
break;
case 2:
TriggerLuaEvent(Name, false, nullptr, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID(), t } }), false);
break;
default:
break;
}
if (a == 2)
break;
a++;
}
}
void GlobalParser(Client* c, const std::string& Pack) {
Assert(c);
if (Pack.empty() || c == nullptr)
return;
std::string Packet = Pack.substr(0, strlen(Pack.c_str()));
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': // initial connection
#ifdef DEBUG
debug(std::string(Sec("got 'P' packet: '")) + Pack + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
Respond(c, Sec("P") + std::to_string(c->GetID()), true);
SyncClient(c);
return;
case 'p':
Respond(c, Sec("p"), false);
UpdatePlayers();
return;
case 'O':
if (Packet.length() > 1000) {
debug(Sec("Received data from: ") + c->GetName() + Sec(" Size: ") + std::to_string(Packet.length()));
}
ParseVeh(c, Packet);
return;
case 'J':
#ifdef DEBUG
debug(std::string(Sec("got 'J' packet: '")) + Pack + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
SendToAll(c, Packet, false, true);
return;
case 'C':
#ifdef DEBUG
debug(std::string(Sec("got 'C' packet: '")) + Pack + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
if (Packet.length() < 4 || Packet.find(':', 3) == std::string::npos)
break;
if (TriggerLuaEvent(Sec("onChatMessage"), false, nullptr,
std::unique_ptr<LuaArg>(new LuaArg {
{ c->GetID(), c->GetName(), Packet.substr(Packet.find(':', 3) + 1) } }),
true))
break;
SendToAll(nullptr, Packet, true, true);
return;
case 'E':
#ifdef DEBUG
debug(std::string(Sec("got 'E' packet: '")) + Pack + Sec("' (") + std::to_string(Packet.size()) + Sec(")"));
#endif
HandleEvent(c, Packet);
return;
default:
return;
}
}
void GParser(Client* c, const std::string& Packet) {
Assert(c);
if (Packet.find("Zp") != std::string::npos && Packet.size() > 500) {
abort();
}
#ifdef WIN32
__try {
GlobalParser(c, Packet);
} __except (Handle(GetExceptionInformation(), Sec("Global Handler"))) { }
#else
GlobalParser(c, Packet);
#endif // WIN32
}
-53
View File
@@ -1,53 +0,0 @@
///
/// Created by Anonymous275 on 4/9/2020
///
#include "CustomAssert.h"
#include <curl/curl.h>
#include <iostream>
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 HttpRequest(const std::string& IP, int port) {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
Assert(curl);
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, IP.c_str());
curl_easy_setopt(curl, CURLOPT_PORT, port);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res != CURLE_OK)
return "-1";
}
return readBuffer;
}
std::string PostHTTP(const std::string& IP, const std::string& Fields) {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
Assert(curl);
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, IP.c_str());
/*curl_easy_setopt(curl, CURLOPT_URL, "https://95.216.35.232/heartbeatv2");
curl_easy_setopt(curl, CURLOPT_PORT, 3600);*/
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, Fields.size());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Fields.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res != CURLE_OK)
return "-1";
}
return readBuffer;
}
-101
View File
@@ -1,101 +0,0 @@
///
/// Created by Anonymous275 on 8/1/2020
///
#include "Client.hpp"
#include "Logger.h"
#include "Lua/LuaSystem.hpp"
#include "Network.h"
#include "Security/Enc.h"
#include "Settings.h"
int OpenID() {
int ID = 0;
bool found;
do {
found = true;
for (auto& 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) {
Assert(c);
char C = MSG.at(0);
if (Rel || C == 'W' || C == 'Y' || C == 'V' || C == 'E') {
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) {
if (!Self)
Assert(c);
char C = Data.at(0);
for (auto& client : CI->Clients) {
if (client != nullptr) {
if (Self || client.get() != c) {
if (client->isSynced) {
if (Rel || C == 'W' || C == 'Y' || C == 'V' || C == 'E') {
if (C == 'O' || C == 'T' || Data.length() > 1000)
SendLarge(client.get(), Data);
else
TCPSend(client.get(), Data);
} else
UDPSend(client.get(), Data);
}
}
}
}
}
void UpdatePlayers() {
std::string Packet = Sec("Ss") + std::to_string(CI->Size()) + "/" + std::to_string(MaxPlayers) + ":";
for (auto& 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) {
Assert(c);
info(c->GetName() + Sec(" Connection Terminated"));
if (c == nullptr)
return;
std::string Packet;
for (auto& 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, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID() } }), false);
CI->RemoveClient(c); ///Removes the Client from existence
}
void OnConnect(Client* c) {
Assert(c);
info(Sec("Client connected"));
c->SetID(OpenID());
info(Sec("Assigned ID ") + std::to_string(c->GetID()) + Sec(" to ") + c->GetName());
TriggerLuaEvent(Sec("onPlayerConnecting"), false, nullptr, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID() } }), false);
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, std::unique_ptr<LuaArg>(new LuaArg { { c->GetID() } }), false);
}
-9
View File
@@ -1,9 +0,0 @@
#include "Network.h"
#include <memory>
#include <thread>
std::unique_ptr<ClientInterface> CI;
void NetMain() {
std::thread TCP(TCPServerMain);
TCP.detach();
UDPServerMain();
}
-44
View File
@@ -1,44 +0,0 @@
///
/// Created by Anonymous275 on 6/18/2020
///
#include "Client.hpp"
#include "Security/Enc.h"
#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 (auto& 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() {
DebugPrintTID();
while (true) {
Monitor();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void StatInit() {
StatReport = "-";
std::thread Init(Stat);
Init.detach();
}
-139
View File
@@ -1,139 +0,0 @@
///
/// Created by Anonymous275 on 8/1/2020
///
#include "Client.hpp"
#include "Logger.h"
#include "Security/Enc.h"
#include "Settings.h"
#include "UnixCompat.h"
#include <fstream>
#ifdef __linux
// we need this for `struct stat`
#include <sys/stat.h>
#endif // __linux
void STCPSend(Client* c, std::string Data) {
Assert(c);
if (c == nullptr)
return;
#ifdef WIN32
int BytesSent;
int len = static_cast<int>(Data.size());
#else
int64_t BytesSent;
size_t len = Data.size();
#endif // WIN32
BytesSent = send(c->GetTCPSock(), Data.c_str(), len, 0);
Data.clear();
if (BytesSent == 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
} else if (BytesSent < 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
info(Sec("Closing socket, BytesSent < 0"));
CloseSocketProper(c->GetTCPSock());
}
}
void SendFile(Client* c, const std::string& Name) {
Assert(c);
info(c->GetName() + Sec(" requesting : ") + Name.substr(Name.find_last_of('/')));
struct stat Info { };
if (stat(Name.c_str(), &Info) != 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 = size_t(fileSize);
size_t Sent = 0;
size_t Diff;
int64_t Split = 64000;
while (c->GetStatus() > -1 && Sent < Size) {
Diff = Size - Sent;
if (Diff > size_t(Split)) {
std::string Data(size_t(Split), 0);
f.seekg(int64_t(Sent), std::ios_base::beg);
f.read(&Data[0], Split);
STCPSend(c, Data);
Sent += size_t(Split);
} else {
std::string Data(Diff, 0);
f.seekg(int64_t(Sent), std::ios_base::beg);
f.read(&Data[0], int64_t(Diff));
STCPSend(c, Data);
Sent += Diff;
}
}
f.close();
}
void Parse(Client* c, const std::string& Packet) {
Assert(c);
if (c == nullptr || Packet.empty())
return;
char Code = Packet.at(0), SubCode = 0;
if (Packet.length() > 1)
SubCode = Packet.at(1);
switch (Code) {
case 'f':
SendFile(c, Packet.substr(1));
return;
case 'S':
if (SubCode == 'R') {
debug(Sec("Sending Mod Info"));
std::string ToSend = FileList + FileSizes;
if (ToSend.empty())
ToSend = "-";
STCPSend(c, ToSend);
}
return;
default:
return;
}
}
bool STCPRecv(Client* c) {
Assert(c);
if (c == nullptr)
return false;
#define len 200
char buf[len];
ZeroMemory(buf, len);
int64_t BytesRcv = recv(c->GetTCPSock(), buf, len, 0);
#undef len
if (BytesRcv == 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
info(Sec("Closing socket in STCP receive, BytesRcv == 0"));
CloseSocketProper(c->GetTCPSock());
return false;
} else if (BytesRcv < 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
info(Sec("Closing socket in STCP receive, BytesRcv < 0"));
CloseSocketProper(c->GetTCPSock());
return false;
}
if (strcmp(buf, "Done") == 0)
return false;
std::string Ret(buf, size_t(BytesRcv));
Parse(c, Ret);
return true;
}
void SyncResources(Client* c) {
Assert(c);
if (c == nullptr)
return;
try {
STCPSend(c, Sec("WS"));
while (c->GetStatus() > -1 && STCPRecv(c))
;
} catch (std::exception& e) {
except(Sec("Exception! : ") + std::string(e.what()));
c->SetStatus(-1);
}
}
-137
View File
@@ -1,137 +0,0 @@
///
/// Created by Anonymous275 on 8/1/2020
///
#include "Compressor.h"
#include "Logger.h"
#include "Network.h"
#include "Security/Enc.h"
#include "UnixCompat.h"
#include <thread>
void TCPSend(Client* c, const std::string& Data) {
Assert(c);
if (c == nullptr)
return;
// Size is BIG ENDIAN now, use only for header!
//auto Size = htonl(int32_t(Data.size()));
///TODO : BIG ENDIAN for other OS
int32_t Size, Sent, Temp;
std::string Send(4, 0);
Size = int32_t(Data.size());
memcpy(&Send[0], &Size, sizeof(Size));
Send += Data;
Sent = 0;
Size += 4;
do {
Temp = send(c->GetTCPSock(), &Send[Sent], Size - Sent, 0);
if (Temp == 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
return;
} else if (Temp < 0) {
if (c->GetStatus() > -1)
c->SetStatus(-1);
// info(Sec("Closing socket, Temp < 0"));
CloseSocketProper(c->GetTCPSock());
return;
}
Sent += Temp;
} while (Sent < Size);
}
bool CheckBytes(Client* c, int32_t BytesRcv) {
Assert(c);
if (BytesRcv == 0) {
debug(Sec("(TCP) Connection closing..."));
if (c->GetStatus() > -1)
c->SetStatus(-1);
return false;
} else if (BytesRcv < 0) {
#ifdef WIN32
debug(Sec("(TCP) recv failed with error: ") + std::to_string(WSAGetLastError()));
#else // unix
debug(Sec("(TCP) recv failed with error: ") + std::string(strerror(errno)));
#endif // WIN32
if (c->GetStatus() > -1)
c->SetStatus(-1);
info(Sec("Closing socket in CheckBytes, BytesRcv < 0"));
CloseSocketProper(c->GetTCPSock());
return false;
}
return true;
}
void TCPRcv(Client* c) {
Assert(c);
int32_t Header, BytesRcv = 0, Temp;
if (c == nullptr || c->GetStatus() < 0)
return;
std::vector<char> Data(sizeof(Header));
do {
Temp = recv(c->GetTCPSock(), &Data[BytesRcv], 4 - BytesRcv, 0);
if (!CheckBytes(c, Temp)) {
#ifdef DEBUG
error(std::string(__func__) + Sec(": failed on CheckBytes in while(BytesRcv < 4)"));
#endif // DEBUG
return;
}
BytesRcv += Temp;
} while (size_t(BytesRcv) < sizeof(Header));
memcpy(&Header, &Data[0], sizeof(Header));
#ifdef DEBUG
//debug(std::string(__func__) + Sec(": expecting ") + std::to_string(Header) + Sec(" bytes."));
#endif // DEBUG
if (!CheckBytes(c, BytesRcv)) {
#ifdef DEBUG
error(std::string(__func__) + Sec(": failed on CheckBytes"));
#endif // DEBUG
return;
}
Data.resize(Header);
BytesRcv = 0;
do {
Temp = recv(c->GetTCPSock(), &Data[BytesRcv], Header - BytesRcv, 0);
if (!CheckBytes(c, Temp)) {
#ifdef DEBUG
error(std::string(__func__) + Sec(": failed on CheckBytes in while(BytesRcv < Header)"));
#endif // DEBUG
return;
}
#ifdef DEBUG
//debug(std::string(__func__) + Sec(": Temp: ") + std::to_string(Temp) + Sec(", BytesRcv: ") + std::to_string(BytesRcv));
#endif // DEBUG
BytesRcv += Temp;
} while (BytesRcv < Header);
#ifdef DEBUG
//debug(std::string(__func__) + Sec(": finished recv with Temp: ") + std::to_string(Temp) + Sec(", BytesRcv: ") + std::to_string(BytesRcv));
#endif // DEBUG
std::string Ret(Data.data(), Header);
if (Ret.substr(0, 4) == "ABG:") {
Ret = DeComp(Ret.substr(4));
}
#ifdef DEBUG
//debug("Parsing from " + c->GetName() + " -> " +std::to_string(Ret.size()));
#endif
GParser(c, Ret);
}
void TCPClient(Client* c) {
DebugPrintTIDInternal(Sec("Client(") + c->GetName() + Sec(")"), true);
Assert(c);
if (c->GetTCPSock() == -1) {
CI->RemoveClient(c);
return;
}
OnConnect(c);
while (c->GetStatus() > -1)
TCPRcv(c);
OnDisconnect(c, c->GetStatus() == -2);
}
void InitClient(Client* c) {
std::thread NewClient(TCPClient, c);
NewClient.detach();
}
-376
View File
@@ -1,376 +0,0 @@
///
/// Created by Anonymous275 on 5/8/2020
///
///UDP
#include "Client.hpp"
#include "Compressor.h"
#include "Logger.h"
#include "Network.h"
#include "Security/Enc.h"
#include "Settings.h"
#include "UnixCompat.h"
#include <array>
#include <cmath>
#include <cstring>
#include <sstream>
#include <thread>
#include <vector>
int FC(const std::string& s, const std::string& p, int n);
struct PacketData {
int ID;
::Client* Client;
std::string Data;
int Tries;
};
struct SplitData {
int Total {};
int ID {};
std::set<std::pair<int, std::string>> Fragments;
};
SOCKET UDPSock;
std::set<PacketData*> DataAcks;
std::set<SplitData*> SplitPackets;
void UDPSend(Client* c, std::string Data) {
Assert(c);
if (c == nullptr || !c->isConnected || c->GetStatus() < 0)
return;
sockaddr_in Addr = c->GetUDPAddr();
socklen_t AddrSize = sizeof(c->GetUDPAddr());
if (Data.length() > 400) {
std::string CMP(Comp(Data));
Data = "ABG:" + CMP;
}
#ifdef WIN32
int sendOk;
int len = static_cast<int>(Data.size());
#else
int64_t sendOk;
size_t len = Data.size();
#endif // WIN32
sendOk = sendto(UDPSock, Data.c_str(), len, 0, (sockaddr*)&Addr, AddrSize);
#ifdef WIN32
if (sendOk == -1) {
debug(Sec("(UDP) Send Failed Code : ") + std::to_string(WSAGetLastError()));
if (c->GetStatus() > -1)
c->SetStatus(-1);
} else if (sendOk == 0) {
debug(Sec("(UDP) sendto returned 0"));
if (c->GetStatus() > -1)
c->SetStatus(-1);
}
#else // unix
if (sendOk == -1) {
debug(Sec("(UDP) Send Failed Code : ") + std::string(strerror(errno)));
if (c->GetStatus() > -1)
c->SetStatus(-1);
} else if (sendOk == 0) {
debug(Sec("(UDP) sendto returned 0"));
if (c->GetStatus() > -1)
c->SetStatus(-1);
}
#endif // WIN32
}
void AckID(int ID) {
for (PacketData* p : DataAcks) {
if (p != nullptr && p->ID == ID) {
DataAcks.erase(p);
break;
}
}
}
int PacktID() {
static int ID = -1;
if (ID > 999999)
ID = 0;
else
ID++;
return ID;
}
int SplitID() {
static int SID = -1;
if (SID > 999999)
SID = 0;
else
SID++;
return SID;
}
void SendLarge(Client* c, std::string Data) {
Assert(c);
if (Data.length() > 400) {
std::string CMP(Comp(Data));
Data = "ABG:" + CMP;
}
TCPSend(c, Data);
}
struct HandledC {
size_t Pos = 0;
Client* c = nullptr;
std::array<int, 100> HandledIDs = { -1 };
};
std::set<HandledC*> HandledIDs;
void ResetIDs(HandledC* H) {
for (size_t C = 0; C < 100; C++) {
H->HandledIDs.at(C) = -1;
}
}
HandledC* GetHandled(Client* c) {
Assert(c);
for (HandledC* h : HandledIDs) {
if (h->c == c) {
return h;
}
}
return new HandledC();
}
bool Handled(Client* c, int ID) {
Assert(c);
bool handle = false;
for (HandledC* h : HandledIDs) {
if (h->c == c) {
for (int id : h->HandledIDs) {
if (id == ID)
return true;
}
if (h->Pos > 99)
h->Pos = 0;
h->HandledIDs.at(h->Pos) = ID;
h->Pos++;
handle = true;
}
}
for (HandledC* h : HandledIDs) {
if (h->c == nullptr || !h->c->isConnected) {
HandledIDs.erase(h);
break;
}
}
if (!handle) {
HandledC* h = GetHandled(c);
ResetIDs(h);
if (h->Pos > 99)
h->Pos = 0;
h->HandledIDs.at(h->Pos) = ID;
h->Pos++;
h->c = c;
HandledIDs.insert(h);
}
return false;
}
std::string UDPRcvFromClient(sockaddr_in& client) {
size_t clientLength = sizeof(client);
ZeroMemory(&client, clientLength);
std::string Ret(10240, 0);
int64_t Rcv = recvfrom(UDPSock, &Ret[0], 10240, 0, (sockaddr*)&client, (socklen_t*)&clientLength);
if (Rcv == -1) {
#ifdef WIN32
error(Sec("(UDP) Error receiving from Client! Code : ") + std::to_string(WSAGetLastError()));
#else // unix
error(Sec("(UDP) Error receiving from Client! Code : ") + std::string(strerror(errno)));
#endif // WIN32
return "";
}
return Ret.substr(0, Rcv);
}
SplitData* GetSplit(int SplitID) {
for (SplitData* a : SplitPackets) {
if (a->ID == SplitID)
return a;
}
auto* SP = new SplitData();
SplitPackets.insert(SP);
return SP;
}
void HandleChunk(Client* c, const std::string& Data) {
Assert(c);
int pos = FC(Data, "|", 5);
if (pos == -1)
return;
std::stringstream ss(Data.substr(0, size_t(pos++)));
std::string t;
int I = -1;
//Current Max ID SID
std::vector<int> Num(4, 0);
while (std::getline(ss, t, '|')) {
if (I >= 0)
Num.at(size_t(I)) = std::stoi(t);
I++;
}
std::string ack = "TRG:" + std::to_string(Num.at(2));
UDPSend(c, ack);
if (Handled(c, Num.at(2))) {
return;
}
std::string Packet = Data.substr(size_t(pos));
SplitData* SData = GetSplit(Num.at(3));
SData->Total = Num.at(1);
SData->ID = Num.at(3);
SData->Fragments.insert(std::make_pair(Num.at(0), Packet));
if (SData->Fragments.size() == size_t(SData->Total)) {
std::string ToHandle;
for (const std::pair<int, std::string>& a : SData->Fragments) {
ToHandle += a.second;
}
GParser(c, ToHandle);
SplitPackets.erase(SData);
delete SData;
SData = nullptr;
}
}
void UDPParser(Client* c, std::string Packet) {
if (Packet.find("Zp") != std::string::npos && Packet.size() > 500) {
abort();
}
Assert(c);
if (Packet.substr(0, 4) == "ABG:") {
Packet = DeComp(Packet.substr(4));
}
if (Packet.substr(0, 4) == "TRG:") {
std::string pkt = Packet.substr(4);
if (Packet.find_first_not_of("0123456789") == std::string::npos) {
AckID(stoi(Packet));
}
return;
} else if (Packet.substr(0, 3) == "BD:") {
auto pos = Packet.find(':', 4);
int ID = stoi(Packet.substr(3, pos - 3));
std::string pkt = "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) == "SC") {
HandleChunk(c, Packet);
return;
}
GParser(c, Packet);
}
void LOOP() {
DebugPrintTID();
while (UDPSock != -1) {
if (!DataAcks.empty()) {
for (PacketData* p : DataAcks) {
if (p != nullptr) {
if (p->Client == nullptr || p->Client->GetTCPSock() == -1) {
DataAcks.erase(p);
break;
}
if (p->Tries < 15) {
UDPSend(p->Client, p->Data);
p->Tries++;
} else {
DataAcks.erase(p);
break;
}
}
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(300));
}
}
[[noreturn]] void UDPServerMain() {
#ifdef WIN32
WSADATA data;
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
serverAddr.sin_family = AF_INET; // Address format is IPv4
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) {
error(Sec("Can't bind socket!") + std::to_string(WSAGetLastError()));
std::this_thread::sleep_for(std::chrono::seconds(5));
_Exit(-1);
//return;
}
DataAcks.clear();
std::thread Ack(LOOP);
Ack.detach();
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) {
try {
sockaddr_in client {};
std::string Data = UDPRcvFromClient(client); //Receives any data from Socket
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 (auto& c : CI->Clients) {
if (c != nullptr && c->GetID() == ID) {
c->SetUDPAddr(client);
c->isConnected = true;
UDPParser(c.get(), Data.substr(2));
}
}
} catch (const std::exception& e) {
error(Sec("fatal: ") + std::string(e.what()));
}
}
/*CloseSocketProper(UDPSock);
WSACleanup();
return;*/
#else // unix
UDPSock = socket(AF_INET, SOCK_DGRAM, 0);
// Create a server hint structure for the server
sockaddr_in serverAddr {};
serverAddr.sin_addr.s_addr = INADDR_ANY; //Any Local
serverAddr.sin_family = AF_INET; // Address format is IPv4
serverAddr.sin_port = htons(uint16_t(Port)); // Convert from little to big endian
// Try and bind the socket to the IP and port
if (bind(UDPSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) != 0) {
error(Sec("Can't bind socket!") + std::string(strerror(errno)));
std::this_thread::sleep_for(std::chrono::seconds(5));
_Exit(-1);
//return;
}
DataAcks.clear();
std::thread Ack(LOOP);
Ack.detach();
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) {
try {
sockaddr_in client {};
std::string Data = UDPRcvFromClient(client); //Receives any data from Socket
size_t Pos = Data.find(':');
if (Data.empty() || 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 = uint8_t(Data.at(0)) - 1;
for (auto& c : CI->Clients) {
if (c != nullptr && c->GetID() == ID) {
c->SetUDPAddr(client);
c->isConnected = true;
UDPParser(c.get(), Data.substr(2));
}
}
} catch (const std::exception& e) {
error(Sec("fatal: ") + std::string(e.what()));
}
}
/*CloseSocketProper(UDPSock); // TODO: Why not this? We did this in TCPServerMain?
return;
*/
#endif // WIN32
}
-56
View File
@@ -1,56 +0,0 @@
///
/// Created by Anonymous275 on 11/6/2020
///
/*#include <boost/beast/core.hpp>
#include "Logger.h"
#include "Security/Enc.h"
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>*/
#include <boost/beast/websocket.hpp>
#include <iostream>
#include <string>
#include <thread>
/*namespace beast = boost::beast;
namespace http = beast::http;
namespace websocket = beast::websocket;
namespace net = boost::asio;
using tcp = boost::asio::ip::tcp;
std::string GetRes(const beast::flat_buffer& buff) {
return (char*)buff.data().data();
}*/
void SyncData() {
/*DebugPrintTID();
try {
std::string const host = Sec("95.216.35.232");
net::io_context ioc;
tcp::resolver r(ioc);
websocket::stream<tcp::socket> ws(ioc);
auto const results = r.resolve(host, Sec("3600"));
net::connect(ws.next_layer(), results.begin(), results.end());
ws.handshake(host, "/");
beast::flat_buffer buffer;
ws.write(boost::asio::buffer("Hello, world!"));
ws.read(buffer);
std::cout << GetRes(buffer) << std::endl;
ws.close(websocket::close_code::normal);
}catch(std::exception const& e){
error(e.what());
std::this_thread::sleep_for(std::chrono::seconds(3));
_Exit(0);
}*/
}
void WebsocketInit() {
/*std::thread t1(SyncData);
t1.detach();*/
}
-139
View File
@@ -1,139 +0,0 @@
///
/// Created by Anonymous275 on 7/17/2020
///
#include "Logger.h"
#include "RWMutex.h"
#include "Security/Enc.h"
#include "Settings.h"
#include <chrono>
#include <fstream>
#include <mutex>
#include <sstream>
#include <thread>
#include <unordered_map>
static RWMutex ThreadNameMapMutex;
static std::unordered_map<std::thread::id, std::string> ThreadNameMap;
std::string ThreadName() {
ReadLock lock(ThreadNameMapMutex);
std::string Name;
if (ThreadNameMap.find(std::this_thread::get_id()) != ThreadNameMap.end()) {
Name = ThreadNameMap.at(std::this_thread::get_id());
} else {
std::stringstream ss;
ss << std::this_thread::get_id();
Name = ss.str();
}
return Name;
}
void SetThreadName(const std::string& Name, bool overwrite) {
WriteLock lock(ThreadNameMapMutex);
if (overwrite || ThreadNameMap.find(std::this_thread::get_id()) == ThreadNameMap.end()) {
ThreadNameMap[std::this_thread::get_id()] = Name;
}
}
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 {};
#ifdef WIN32
localtime_s(&local_tm, &tt);
#else // unix
localtime_r(&tt, &local_tm);
#endif // WIN32
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
<< "["
<< local_tm.tm_mday << "/"
<< local_tm.tm_mon + 1 << "/"
<< local_tm.tm_year + 1900 << " "
<< Hour << ":"
<< Min << ":"
<< Secs
<< "] ";
if (Debug) {
date << ThreadName()
<< " ";
}
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();
}
std::mutex LogLock;
void DebugPrintTIDInternal(const std::string& func, bool overwrite) {
// we need to print to cout here as we might crash before all console output is handled,
// due to segfaults or asserts.
SetThreadName(func, overwrite);
#ifdef DEBUG
std::scoped_lock Guard(LogLock);
std::stringstream Print;
Print << "(debug build) Thread '" << std::this_thread::get_id() << "' is " << func << "\n";
ConsoleOut(Print.str());
#endif // DEBUG
}
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) {
std::scoped_lock Guard(LogLock);
std::string Print = getDate() + Sec("[INFO] ") + toPrint + "\n";
ConsoleOut(Print);
addToLog(Print);
}
void debug(const std::string& toPrint) {
if (!Debug)
return;
std::scoped_lock Guard(LogLock);
std::string Print = getDate() + Sec("[DEBUG] ") + toPrint + "\n";
ConsoleOut(Print);
addToLog(Print);
}
void warn(const std::string& toPrint) {
std::scoped_lock Guard(LogLock);
std::string Print = getDate() + Sec("[WARN] ") + toPrint + "\n";
ConsoleOut(Print);
addToLog(Print);
}
void error(const std::string& toPrint) {
std::scoped_lock Guard(LogLock);
std::string Print = getDate() + Sec("[ERROR] ") + toPrint + "\n";
ConsoleOut(Print);
addToLog(Print);
}
void except(const std::string& toPrint) {
std::scoped_lock Guard(LogLock);
std::string Print = getDate() + Sec("[EXCEP] ") + toPrint + "\n";
ConsoleOut(Print);
addToLog(Print);
}
-53
View File
@@ -1,53 +0,0 @@
#include "CustomAssert.h"
#include "Security/Xor.h"
#include "Startup.h"
#include <curl/curl.h>
#include <iostream>
#include <thread>
#ifndef WIN32
#include <signal.h>
void UnixSignalHandler(int sig) {
switch (sig) {
case SIGPIPE:
warn(Sec("ignored signal SIGPIPE: Pipe broken"));
break;
default:
error(Sec("Signal arrived in handler but was not handled: ") + std::to_string(sig));
break;
}
}
#endif // WIN32
[[noreturn]] void loop() {
DebugPrintTID();
while (true) {
std::cout.flush();
std::this_thread::sleep_for(std::chrono::milliseconds(600));
}
}
int main(int argc, char* argv[]) {
#ifndef WIN32
// ignore SIGPIPE, the signal that is sent for example when a client
// disconnects while data is being sent to him ("broken pipe").
signal(SIGPIPE, UnixSignalHandler);
#endif // WIN32
DebugPrintTID();
// curl needs to be initialized to properly deallocate its resources later
Assert(curl_global_init(CURL_GLOBAL_DEFAULT) == CURLE_OK);
#ifdef DEBUG
std::thread t1(loop);
t1.detach();
#endif
ConsoleInit();
InitServer(argc, argv);
InitConfig();
InitLua();
InitRes();
HBInit();
StatInit();
NetMain();
// clean up curl at the end to be sure
curl_global_cleanup();
return 0;
}