mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2025-07-04 00:47:23 +00:00
Merge branch 'master' into patch-1
This commit is contained in:
commit
16ea84b4cf
@ -7,7 +7,7 @@
|
|||||||
///
|
///
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
void PreGame(int argc, char* argv[],const std::string& GamePath);
|
void PreGame(const std::string& GamePath);
|
||||||
std::string CheckVer(const std::string &path);
|
std::string CheckVer(const std::string &path);
|
||||||
void InitGame(const std::string& Dir);
|
void InitGame(const std::string& Dir);
|
||||||
std::string GetGameDir();
|
std::string GetGameDir();
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include "Startup.h"
|
#include "Startup.h"
|
||||||
#include <ShlObj.h>
|
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -23,19 +22,19 @@ std::string GetGamePath(){
|
|||||||
LPCTSTR sk = "Software\\BeamNG\\BeamNG.drive";
|
LPCTSTR sk = "Software\\BeamNG\\BeamNG.drive";
|
||||||
LONG openRes = RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey);
|
LONG openRes = RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey);
|
||||||
if (openRes != ERROR_SUCCESS){
|
if (openRes != ERROR_SUCCESS){
|
||||||
fatal("Please launch the game at least once");
|
fatal("Please launch the game at least once!");
|
||||||
}
|
}
|
||||||
Path = QueryKey(hKey,4);
|
Path = QueryKey(hKey,4);
|
||||||
|
|
||||||
if(Path.empty()){
|
if(Path.empty()){
|
||||||
CoInitialize(nullptr);
|
sk = R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders)";
|
||||||
wchar_t * path = nullptr;
|
openRes = RegOpenKeyEx(HKEY_CURRENT_USER, sk, 0, KEY_ALL_ACCESS, &hKey);
|
||||||
SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_SIMPLE_IDLIST, nullptr, (PWSTR *)(&path));
|
if (openRes != ERROR_SUCCESS){
|
||||||
CoTaskMemFree(path);
|
fatal("Cannot get Documents directory!");
|
||||||
std::wstring ws(path);
|
}
|
||||||
std::string s(ws.begin(), ws.end());
|
Path = QueryKey(hKey,5);
|
||||||
Path = s;
|
|
||||||
Path += "\\BeamNG.drive\\";
|
Path += "\\BeamNG.drive\\";
|
||||||
|
return Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Path;
|
return Path;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
namespace fs = std::experimental::filesystem;
|
namespace fs = std::filesystem;
|
||||||
std::string ListOfMods;
|
std::string ListOfMods;
|
||||||
std::vector<std::string> Split(const std::string& String,const std::string& delimiter){
|
std::vector<std::string> Split(const std::string& String,const std::string& delimiter){
|
||||||
std::vector<std::string> Val;
|
std::vector<std::string> Val;
|
||||||
@ -126,11 +126,10 @@ char* TCPRcvRaw(SOCKET Sock,uint64_t& GRcv, uint64_t Size){
|
|||||||
}
|
}
|
||||||
char* File = new char[Size];
|
char* File = new char[Size];
|
||||||
uint64_t Rcv = 0;
|
uint64_t Rcv = 0;
|
||||||
int32_t Temp;
|
|
||||||
do{
|
do{
|
||||||
int Len = int(Size-Rcv);
|
int Len = int(Size-Rcv);
|
||||||
if(Len > 1000000)Len = 1000000;
|
if(Len > 1000000)Len = 1000000;
|
||||||
Temp = recv(Sock, &File[Rcv], Len, MSG_WAITALL);
|
int32_t Temp = recv(Sock, &File[Rcv], Len, MSG_WAITALL);
|
||||||
if(Temp < 1){
|
if(Temp < 1){
|
||||||
info(std::to_string(Temp));
|
info(std::to_string(Temp));
|
||||||
UUl("Socket Closed Code 1");
|
UUl("Socket Closed Code 1");
|
||||||
@ -153,6 +152,7 @@ SOCKET InitDSock(){
|
|||||||
SOCKET DSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
SOCKET DSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
SOCKADDR_IN ServerAddr;
|
SOCKADDR_IN ServerAddr;
|
||||||
if(DSock < 1){
|
if(DSock < 1){
|
||||||
|
KillSocket(DSock);
|
||||||
Terminate = true;
|
Terminate = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -252,12 +252,12 @@ void SyncResources(SOCKET Sock){
|
|||||||
Pos++;
|
Pos++;
|
||||||
if (fs::exists(a)) {
|
if (fs::exists(a)) {
|
||||||
if (FS->find_first_not_of("0123456789") != std::string::npos)continue;
|
if (FS->find_first_not_of("0123456789") != std::string::npos)continue;
|
||||||
if (fs::file_size(a) == std::stoi(*FS)){
|
if (fs::file_size(a) == std::stoull(*FS)){
|
||||||
UpdateUl(false,std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + a.substr(a.find_last_of('/')));
|
UpdateUl(false,std::to_string(Pos) + "/" + std::to_string(Amount) + ": " + a.substr(a.find_last_of('/')));
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
try {
|
try {
|
||||||
if(!fs::exists(GetGamePath() + "mods/multiplayer")){
|
if(!fs::exists(GetGamePath() + "mods/multiplayer")){
|
||||||
fs::create_directory(GetGamePath() + "mods/multiplayer");
|
fs::create_directories(GetGamePath() + "mods/multiplayer");
|
||||||
}
|
}
|
||||||
fs::copy_file(a, GetGamePath() + "mods/multiplayer" + a.substr(a.find_last_of('/')),
|
fs::copy_file(a, GetGamePath() + "mods/multiplayer" + a.substr(a.find_last_of('/')),
|
||||||
fs::copy_options::overwrite_existing);
|
fs::copy_options::overwrite_existing);
|
||||||
@ -295,10 +295,10 @@ void SyncResources(SOCKET Sock){
|
|||||||
LFS.close();
|
LFS.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}while(fs::file_size(a) != std::stoi(*FS) && !Terminate);
|
}while(fs::file_size(a) != std::stoull(*FS) && !Terminate);
|
||||||
if(!Terminate){
|
if(!Terminate){
|
||||||
if(!fs::exists(GetGamePath() + "mods/multiplayer")){
|
if(!fs::exists(GetGamePath() + "mods/multiplayer")){
|
||||||
fs::create_directory(GetGamePath() + "mods/multiplayer");
|
fs::create_directories(GetGamePath() + "mods/multiplayer");
|
||||||
}
|
}
|
||||||
fs::copy_file(a,GetGamePath() + "mods/multiplayer" + FName, fs::copy_options::overwrite_existing);
|
fs::copy_file(a,GetGamePath() + "mods/multiplayer" + FName, fs::copy_options::overwrite_existing);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <ShlDisp.h>
|
||||||
|
|
||||||
#define MAX_KEY_LENGTH 255
|
#define MAX_KEY_LENGTH 255
|
||||||
#define MAX_VALUE_NAME 16383
|
#define MAX_VALUE_NAME 16383
|
||||||
@ -106,16 +107,21 @@ std::string QueryKey(HKEY hKey,int ID){
|
|||||||
DWORD lpData = cbMaxValueData;
|
DWORD lpData = cbMaxValueData;
|
||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
LONG dwRes = RegQueryValueEx(hKey, achValue, nullptr, nullptr, buffer, &lpData);
|
LONG dwRes = RegQueryValueEx(hKey, achValue, nullptr, nullptr, buffer, &lpData);
|
||||||
std::string data = reinterpret_cast<const char *const>(buffer);
|
std::string data = (char *)(buffer);
|
||||||
std::string key = achValue;
|
std::string key = achValue;
|
||||||
|
|
||||||
switch (ID){
|
switch (ID){
|
||||||
case 1: if(key == "SteamExe"){
|
case 1: if(key == "SteamExe"){
|
||||||
auto p = data.find_last_of('/');
|
auto p = data.find_last_of("/\\");
|
||||||
if(p != std::string::npos)return data.substr(0,p);
|
if(p != std::string::npos){
|
||||||
}break;
|
return data.substr(0,p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 2: if(key == "Name" && data == "BeamNG.drive")return data;break;
|
case 2: if(key == "Name" && data == "BeamNG.drive")return data;break;
|
||||||
case 3: if(key == "rootpath")return data;break;
|
case 3: if(key == "rootpath")return data;break;
|
||||||
case 4: if(key == "userpath_override")return data;
|
case 4: if(key == "userpath_override")return data;
|
||||||
|
case 5: if(key == "Personal")return data;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,18 +130,17 @@ std::string QueryKey(HKEY hKey,int ID){
|
|||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
namespace fs = std::experimental::filesystem;
|
namespace fs = std::filesystem;
|
||||||
void FileList(std::vector<std::string>&a,const std::string& Path){
|
void FileList(std::vector<std::string>&a,const std::string& Path){
|
||||||
for (const auto &entry : fs::directory_iterator(Path)) {
|
for (const auto &entry : fs::directory_iterator(Path)) {
|
||||||
auto pos = entry.path().filename().string().find('.');
|
if (!entry.is_directory()) {
|
||||||
if (pos != std::string::npos) {
|
a.emplace_back(entry.path().u8string());
|
||||||
a.emplace_back(entry.path().string());
|
}else FileList(a,entry.path().u8string());
|
||||||
}else FileList(a,entry.path().string());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool Find(const std::string& FName,const std::string& Path){
|
bool Find(const std::string& FName,const std::string& Path){
|
||||||
std::vector<std::string> FS;
|
std::vector<std::string> FS;
|
||||||
FileList(FS,Path+"/userdata");
|
FileList(FS,Path+"\\userdata");
|
||||||
for(std::string&a : FS){
|
for(std::string&a : FS){
|
||||||
if(a.find(FName) != std::string::npos){
|
if(a.find(FName) != std::string::npos){
|
||||||
FS.clear();
|
FS.clear();
|
||||||
@ -148,7 +153,7 @@ bool Find(const std::string& FName,const std::string& Path){
|
|||||||
bool FindHack(const std::string& Path){
|
bool FindHack(const std::string& Path){
|
||||||
bool s = true;
|
bool s = true;
|
||||||
for (const auto &entry : fs::directory_iterator(Path)) {
|
for (const auto &entry : fs::directory_iterator(Path)) {
|
||||||
std::string Name = entry.path().filename().string();
|
std::string Name = entry.path().filename().u8string();
|
||||||
for(char&c : Name)c = char(tolower(c));
|
for(char&c : Name)c = char(tolower(c));
|
||||||
if(Name == "steam.exe")s = false;
|
if(Name == "steam.exe")s = false;
|
||||||
if(Name.find("greenluma") != -1)return true;
|
if(Name.find("greenluma") != -1)return true;
|
||||||
@ -225,8 +230,8 @@ bool IDCheck(std::string Man, std::string steam){
|
|||||||
bool a = false,b = true;
|
bool a = false,b = true;
|
||||||
int pos = int(Man.rfind("steamapps"));
|
int pos = int(Man.rfind("steamapps"));
|
||||||
if(pos == -1)Exit(5);
|
if(pos == -1)Exit(5);
|
||||||
Man = Man.substr(0,pos+9) + "/appmanifest_284160.acf";
|
Man = Man.substr(0,pos+9) + "\\appmanifest_284160.acf";
|
||||||
steam += "/config/loginusers.vdf";
|
steam += "\\config\\loginusers.vdf";
|
||||||
if(fs::exists(Man) && fs::exists(steam)){
|
if(fs::exists(Man) && fs::exists(steam)){
|
||||||
for(const std::string&ID : GetID(steam)){
|
for(const std::string&ID : GetID(steam)){
|
||||||
if(ID == GetManifest(Man))b = false;
|
if(ID == GetManifest(Man))b = false;
|
||||||
@ -241,22 +246,27 @@ void LegitimacyCheck(){
|
|||||||
std::string K2 = R"(Software\Valve\Steam\Apps\284160)";
|
std::string K2 = R"(Software\Valve\Steam\Apps\284160)";
|
||||||
std::string K3 = R"(Software\BeamNG\BeamNG.drive)";
|
std::string K3 = R"(Software\BeamNG\BeamNG.drive)";
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
|
|
||||||
LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey);
|
LONG dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K1.c_str(), &hKey);
|
||||||
|
|
||||||
if(dwRegOPenKey == ERROR_SUCCESS) {
|
if(dwRegOPenKey == ERROR_SUCCESS) {
|
||||||
Result = QueryKey(hKey, 1);
|
Result = QueryKey(hKey, 1);
|
||||||
if(Result.empty())Exit(1);
|
if(Result.empty())Exit(1);
|
||||||
|
|
||||||
if(fs::exists(Result)){
|
if(fs::exists(Result)){
|
||||||
if(!Find("284160.json",Result))Exit(2);
|
if(!Find("284160.json",Result))Exit(2);
|
||||||
if(FindHack(Result)) {
|
if(FindHack(Result)) {
|
||||||
std::string maliciousFileName = fs::directory_iterator(Result).path().filename().string();
|
std::string maliciousFileName = fs::directory_iterator(Result)->path().filename().string();
|
||||||
error("Found malicious file " + maliciousFileName + ". Please remove it in order to play\n");
|
error("Found malicious file " + maliciousFileName + ". Please remove it in order to play\n");
|
||||||
SteamExit(1);
|
SteamExit(1);
|
||||||
}
|
}
|
||||||
}else Exit(3);
|
}else Exit(3);
|
||||||
|
|
||||||
T = Result;
|
T = Result;
|
||||||
Result.clear();
|
Result.clear();
|
||||||
TraceBack++;
|
TraceBack++;
|
||||||
}else Exit(4);
|
}else Exit(4);
|
||||||
|
|
||||||
K1.clear();
|
K1.clear();
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K2.c_str(), &hKey);
|
dwRegOPenKey = OpenKey(HKEY_CURRENT_USER, K2.c_str(), &hKey);
|
||||||
|
@ -40,6 +40,11 @@ std::string GetFail(const std::string& R){
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string Login(const std::string& fields){
|
std::string Login(const std::string& fields){
|
||||||
|
if(fields == "LO"){
|
||||||
|
LoginAuth = false;
|
||||||
|
UpdateKey(nullptr);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
info("Attempting to authenticate...");
|
info("Attempting to authenticate...");
|
||||||
std::string Buffer = PostHTTP("https://auth.beammp.com/userlogin", fields);
|
std::string Buffer = PostHTTP("https://auth.beammp.com/userlogin", fields);
|
||||||
json::Document d;
|
json::Document d;
|
||||||
@ -47,6 +52,7 @@ std::string Login(const std::string& fields){
|
|||||||
if(Buffer == "-1"){
|
if(Buffer == "-1"){
|
||||||
return GetFail("Failed to communicate with the auth system!");
|
return GetFail("Failed to communicate with the auth system!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Buffer.find('{') == -1 || d.HasParseError()) {
|
if (Buffer.find('{') == -1 || d.HasParseError()) {
|
||||||
return GetFail("Invalid answer from authentication servers, please try again later!");
|
return GetFail("Invalid answer from authentication servers, please try again later!");
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
extern int TraceBack;
|
extern int TraceBack;
|
||||||
bool Dev = false;
|
bool Dev = false;
|
||||||
namespace fs = std::experimental::filesystem;
|
namespace fs = std::filesystem;
|
||||||
std::string GetEN(){
|
std::string GetEN(){
|
||||||
return "BeamMP-Launcher.exe";
|
return "BeamMP-Launcher.exe";
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ std::string GetVer(){
|
|||||||
return "1.80";
|
return "1.80";
|
||||||
}
|
}
|
||||||
std::string GetPatch(){
|
std::string GetPatch(){
|
||||||
return ".2";
|
return ".10";
|
||||||
}
|
}
|
||||||
void ReLaunch(int argc,char*args[]){
|
void ReLaunch(int argc,char*args[]){
|
||||||
std::string Arg;
|
std::string Arg;
|
||||||
@ -118,9 +118,7 @@ void CheckForUpdates(int argc,char*args[],const std::string& CV){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
URelaunch(argc,args);
|
URelaunch(argc,args);
|
||||||
}else{
|
}else info("Version is up to date");
|
||||||
info("Version is up to date");
|
|
||||||
}
|
|
||||||
TraceBack++;
|
TraceBack++;
|
||||||
}
|
}
|
||||||
void CheckDir(int argc,char*args[]){
|
void CheckDir(int argc,char*args[]){
|
||||||
@ -182,55 +180,28 @@ void InitLauncher(int argc, char* argv[]) {
|
|||||||
CheckName(argc, argv);
|
CheckName(argc, argv);
|
||||||
CheckLocalKey(); //will replace RequestRole
|
CheckLocalKey(); //will replace RequestRole
|
||||||
Discord_Main();
|
Discord_Main();
|
||||||
Dev = true;
|
//Dev = true;
|
||||||
//RequestRole();
|
//RequestRole();
|
||||||
CustomPort(argc, argv);
|
CustomPort(argc, argv);
|
||||||
CheckForUpdates(argc, argv, std::string(GetVer()) + GetPatch());
|
CheckForUpdates(argc, argv, std::string(GetVer()) + GetPatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreGame(int argc, char* argv[],const std::string& GamePath){
|
void PreGame(const std::string& GamePath){
|
||||||
info("Game Version : " + CheckVer(GamePath));
|
info("Game Version : " + CheckVer(GamePath));
|
||||||
std::string DUI = R"(BeamNG\settings\uiapps-layouts.json)";
|
|
||||||
std::string GS = R"(BeamNG\settings\game-settings.ini)";
|
|
||||||
std::string link = "https://beammp.com/client-ui-data";
|
|
||||||
bool fallback = false;
|
|
||||||
int i;
|
|
||||||
if(!fs::exists(DUI)){
|
|
||||||
info("Downloading default ui data...");
|
|
||||||
i = Download(link,DUI,true);
|
|
||||||
if(i != -1){
|
|
||||||
fallback = true;
|
|
||||||
remove(DUI.c_str());
|
|
||||||
link = "https://backup1.beammp.com/client-ui-data";
|
|
||||||
i = Download(link,DUI,true);
|
|
||||||
if(i != -1) {
|
|
||||||
error("Failed to download code : " + std::to_string(i));
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
|
||||||
ReLaunch(argc, argv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
info("Download Complete!");
|
|
||||||
}
|
|
||||||
if(!fs::exists(GS)) {
|
|
||||||
info("Downloading default game settings...");
|
|
||||||
if(fallback)link = "https://backup1.beammp.com/client-settings-data";
|
|
||||||
else link = "https://beammp.com/client-settings-data";
|
|
||||||
Download(link, GS,true);
|
|
||||||
info("Download Complete!");
|
|
||||||
}
|
|
||||||
if(!Dev) {
|
if(!Dev) {
|
||||||
info("Downloading mod...");
|
info("Downloading mod...");
|
||||||
if(fallback)link = "https://backup1.beammp.com/builds/client";
|
try {
|
||||||
else link ="https://beammp.com/builds/client";
|
if (!fs::exists(GetGamePath() + "mods/multiplayer")) {
|
||||||
if(!fs::exists(GetGamePath() + "mods")){
|
fs::create_directories(GetGamePath() + "mods/multiplayer");
|
||||||
fs::create_directory(GetGamePath() + "mods");
|
}
|
||||||
|
}catch(std::exception&e){
|
||||||
|
fatal(e.what());
|
||||||
}
|
}
|
||||||
if(!fs::exists(GetGamePath() + "mods/multiplayer")){
|
Download("https://beammp.com/builds/client", GetGamePath() + R"(mods\multiplayer\BeamMP.zip)", true);
|
||||||
fs::create_directory(GetGamePath() + "mods/multiplayer");
|
|
||||||
}
|
|
||||||
Download(link, GetGamePath() + R"(mods\multiplayer\BeamMP.zip)", true);
|
|
||||||
info("Download Complete!");
|
info("Download Complete!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*debug("Name : " + GetDName());
|
/*debug("Name : " + GetDName());
|
||||||
debug("Discriminator : " + GetDTag());
|
debug("Discriminator : " + GetDTag());
|
||||||
debug("Unique ID : " + GetDID());*/
|
debug("Unique ID : " + GetDID());*/
|
||||||
|
16
src/main.cpp
16
src/main.cpp
@ -8,13 +8,15 @@
|
|||||||
#include "Network/network.h"
|
#include "Network/network.h"
|
||||||
#include "Security/Init.h"
|
#include "Security/Init.h"
|
||||||
#include "Startup.h"
|
#include "Startup.h"
|
||||||
#include <thread>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "Logger.h"
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
|
||||||
[[noreturn]] void flush(){
|
[[noreturn]] void flush(){
|
||||||
while(true){
|
while(true){
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,9 +26,13 @@ int main(int argc, char* argv[]) {
|
|||||||
th.detach();
|
th.detach();
|
||||||
#endif
|
#endif
|
||||||
InitLauncher(argc,argv);
|
InitLauncher(argc,argv);
|
||||||
CheckDir(argc,argv);
|
//CheckDir(argc,argv);
|
||||||
LegitimacyCheck();
|
try {
|
||||||
PreGame(argc,argv,GetGameDir());
|
LegitimacyCheck();
|
||||||
|
}catch (std::exception&e){
|
||||||
|
fatal("Main 1 : " + std::string(e.what()));
|
||||||
|
}
|
||||||
|
PreGame(GetGameDir());
|
||||||
InitGame(GetGameDir());
|
InitGame(GetGameDir());
|
||||||
CoreNetwork();
|
CoreNetwork();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user