mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2025-10-27 14:50:05 +00:00
Compare commits
5 Commits
02c1c681dd
...
lua-more-b
| Author | SHA1 | Date | |
|---|---|---|---|
| d32dd4c319 | |||
| c5de584762 | |||
| 450cc78c9a | |||
| 95f2920f5c | |||
| 27ccda5b10 |
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
version.h
|
||||||
38
.github/workflows/push-docker-image.yml
vendored
38
.github/workflows/push-docker-image.yml
vendored
@@ -1,38 +0,0 @@
|
|||||||
name: Push Docker Image
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
push-docker-image:
|
|
||||||
name: Push Docker Image
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
platforms:
|
|
||||||
- linux/amd64
|
|
||||||
- linux/arm64
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Retrieve major version
|
|
||||||
uses: winterjung/split@v2
|
|
||||||
id: split
|
|
||||||
with:
|
|
||||||
msg: ${{ github.ref_name }}
|
|
||||||
separator: .
|
|
||||||
- name: Log in to registry
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
- name: Build and push the Docker image
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./Dockerfile
|
|
||||||
platforms: ${{ matrix.platforms }}
|
|
||||||
push: true
|
|
||||||
tags: ${{ secrets.DOCKERHUB_REPOSITORY }}:${{ github.ref_name }},${{ secrets.DOCKERHUB_REPOSITORY }}:${{ steps.split.outputs._0 }},${{ secrets.DOCKERHUB_REPOSITORY }}:latest
|
|
||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
|||||||
[submodule "tdata"]
|
[submodule "tdata"]
|
||||||
path = tdata
|
path = tdata
|
||||||
url = https://github.com/OpenFusionProject/tabledata.git
|
url = https://github.com/OpenFusionProject/tabledata.git
|
||||||
|
[submodule "vendor/Lua"]
|
||||||
|
path = vendor/Lua
|
||||||
|
url = https://github.com/walterschell/Lua.git
|
||||||
|
|||||||
@@ -34,20 +34,28 @@ else()
|
|||||||
set(BIN_NAME fusion)
|
set(BIN_NAME fusion)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# add lua
|
||||||
|
option(LUA_BUILD_COMPILER OFF)
|
||||||
|
option(LUA_ENABLE_SHARED OFF)
|
||||||
|
option(LUA_ENABLE_TESTING OFF)
|
||||||
|
add_subdirectory(vendor/Lua)
|
||||||
|
|
||||||
include_directories(src vendor)
|
include_directories(src vendor)
|
||||||
|
|
||||||
file(GLOB_RECURSE SOURCES src/**.[ch]pp vendor/**.[ch]pp vendor/**.[ch] version.h)
|
file(GLOB_RECURSE VENDOR_SOURCES vendor/bcrypt/**.[ch] vendor/mingw/**.h vendor/INIReader.hpp vendor/JSON.hpp)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE SOURCES src/**.[ch]pp version.h)
|
||||||
|
|
||||||
configure_file(version.h.in ${CMAKE_SOURCE_DIR}/version.h @ONLY)
|
configure_file(version.h.in ${CMAKE_SOURCE_DIR}/version.h @ONLY)
|
||||||
|
|
||||||
add_executable(openfusion ${SOURCES})
|
add_executable(openfusion ${SOURCES} ${VENDOR_SOURCES})
|
||||||
|
|
||||||
set_target_properties(openfusion PROPERTIES OUTPUT_NAME ${BIN_NAME})
|
set_target_properties(openfusion PROPERTIES OUTPUT_NAME ${BIN_NAME})
|
||||||
|
|
||||||
# find sqlite3 and use it
|
# find sqlite3 and use it
|
||||||
find_package(SQLite3 REQUIRED)
|
find_package(SQLite3 REQUIRED)
|
||||||
target_include_directories(openfusion PRIVATE ${SQLite3_INCLUDE_DIRS})
|
target_include_directories(openfusion PRIVATE ${SQLite3_INCLUDE_DIRS})
|
||||||
target_link_libraries(openfusion PRIVATE ${SQLite3_LIBRARIES})
|
target_link_libraries(openfusion PRIVATE lua_static ${SQLite3_LIBRARIES})
|
||||||
|
|
||||||
# Makes it so config, tdata, etc. get picked up when starting via the debugger in VS
|
# Makes it so config, tdata, etc. get picked up when starting via the debugger in VS
|
||||||
set_property(TARGET openfusion PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
set_property(TARGET openfusion PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||||
|
|||||||
25
Dockerfile
25
Dockerfile
@@ -1,5 +1,4 @@
|
|||||||
# build
|
FROM debian:latest
|
||||||
FROM debian:stable-slim as build
|
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
@@ -9,24 +8,14 @@ clang \
|
|||||||
make \
|
make \
|
||||||
libsqlite3-dev
|
libsqlite3-dev
|
||||||
|
|
||||||
COPY src ./src
|
COPY . ./
|
||||||
COPY vendor ./vendor
|
|
||||||
COPY .git ./.git
|
|
||||||
COPY Makefile CMakeLists.txt version.h.in ./
|
|
||||||
|
|
||||||
RUN make -j8
|
RUN make -j8
|
||||||
|
|
||||||
# prod
|
# tabledata should be copied from the host;
|
||||||
FROM debian:stable-slim
|
# clone it there before building the container
|
||||||
|
#RUN git submodule update --init --recursive
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
CMD ["./bin/fusion"]
|
||||||
|
|
||||||
RUN apt-get -y update && apt-get install -y \
|
LABEL Name=openfusion Version=0.0.1
|
||||||
libsqlite3-dev
|
|
||||||
|
|
||||||
COPY --from=build /usr/src/app/bin/fusion /bin/fusion
|
|
||||||
COPY sql ./sql
|
|
||||||
|
|
||||||
CMD ["/bin/fusion"]
|
|
||||||
|
|
||||||
LABEL Name=openfusion Version=0.0.2
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2020-2024 OpenFusion Contributors
|
Copyright (c) 2020-2023 OpenFusion Contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -95,6 +95,8 @@ CXXHDR=\
|
|||||||
vendor/bcrypt/BCrypt.hpp\
|
vendor/bcrypt/BCrypt.hpp\
|
||||||
vendor/INIReader.hpp\
|
vendor/INIReader.hpp\
|
||||||
vendor/JSON.hpp\
|
vendor/JSON.hpp\
|
||||||
|
vendor/INIReader.hpp\
|
||||||
|
vendor/JSON.hpp\
|
||||||
src/Buffs.hpp\
|
src/Buffs.hpp\
|
||||||
src/Chat.hpp\
|
src/Chat.hpp\
|
||||||
src/CustomCommands.hpp\
|
src/CustomCommands.hpp\
|
||||||
|
|||||||
@@ -66,9 +66,6 @@ motd=Welcome to OpenFusion!
|
|||||||
# location of the database
|
# location of the database
|
||||||
#dbpath=database.db
|
#dbpath=database.db
|
||||||
|
|
||||||
# should there be a score cap for infected zone races?
|
|
||||||
#izracescorecapped=true
|
|
||||||
|
|
||||||
# should tutorial flags be disabled off the bat?
|
# should tutorial flags be disabled off the bat?
|
||||||
disablefirstuseflag=true
|
disablefirstuseflag=true
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
volumes:
|
|
||||||
- ./config.ini:/usr/src/app/config.ini
|
|
||||||
- ./database.db:/usr/src/app/database.db
|
|
||||||
- ./tdata:/usr/src/app/tdata
|
|
||||||
ports:
|
ports:
|
||||||
- "23000:23000"
|
- "23000:23000"
|
||||||
- "23001:23001"
|
- "23001:23001"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ static bool playerHasBuddyWithID(Player* plr, int buddyID) {
|
|||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
// Refresh buddy list
|
// Refresh buddy list
|
||||||
void Buddies::sendBuddyList(CNSocket* sock) {
|
void Buddies::refreshBuddyList(CNSocket* sock) {
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
int buddyCnt = Database::getNumBuddies(plr);
|
int buddyCnt = Database::getNumBuddies(plr);
|
||||||
|
|
||||||
@@ -277,6 +277,15 @@ static void reqFindNameBuddyAccept(CNSocket* sock, CNPacketData* data) {
|
|||||||
// Getting buddy state
|
// Getting buddy state
|
||||||
static void reqPktGetBuddyState(CNSocket* sock, CNPacketData* data) {
|
static void reqPktGetBuddyState(CNSocket* sock, CNPacketData* data) {
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the buddy list wasn't synced a second time yet, sync it.
|
||||||
|
* Not sure why we have to do it again for the client not to trip up.
|
||||||
|
*/
|
||||||
|
if (!plr->buddiesSynced) {
|
||||||
|
refreshBuddyList(sock);
|
||||||
|
plr->buddiesSynced = true;
|
||||||
|
}
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_GET_BUDDY_STATE_SUCC, resp);
|
INITSTRUCT(sP_FE2CL_REP_GET_BUDDY_STATE_SUCC, resp);
|
||||||
|
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ namespace Buddies {
|
|||||||
void init();
|
void init();
|
||||||
|
|
||||||
// Buddy list
|
// Buddy list
|
||||||
void sendBuddyList(CNSocket* sock);
|
void refreshBuddyList(CNSocket* sock);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,77 +83,7 @@ static void helpCommand(std::string full, std::vector<std::string>& args, CNSock
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void accessCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
static void accessCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
if (args.size() < 2) {
|
Chat::sendServerMessage(sock, "Your access level is " + std::to_string(PlayerManager::getPlayer(sock)->accountLevel));
|
||||||
Chat::sendServerMessage(sock, "Usage: /access <id> [new_level]");
|
|
||||||
Chat::sendServerMessage(sock, "Use . for id to select yourself");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *tmp;
|
|
||||||
|
|
||||||
Player* self = PlayerManager::getPlayer(sock);
|
|
||||||
int selfAccess = self->accountLevel;
|
|
||||||
|
|
||||||
Player* player;
|
|
||||||
if (args[1].compare(".") == 0) {
|
|
||||||
player = self;
|
|
||||||
} else {
|
|
||||||
int id = std::strtol(args[1].c_str(), &tmp, 10);
|
|
||||||
if (*tmp) {
|
|
||||||
Chat::sendServerMessage(sock, "Invalid player ID " + args[1]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
player = PlayerManager::getPlayerFromID(id);
|
|
||||||
if (player == nullptr) {
|
|
||||||
Chat::sendServerMessage(sock, "Could not find player with ID " + std::to_string(id));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Messing with other players requires a baseline access of 30
|
|
||||||
if (player != self && selfAccess > 30) {
|
|
||||||
Chat::sendServerMessage(sock, "Can't check or change other players access levels (insufficient privileges)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string playerName = PlayerManager::getPlayerName(player);
|
|
||||||
int currentAccess = player->accountLevel;
|
|
||||||
if (args.size() < 3) {
|
|
||||||
// just check
|
|
||||||
Chat::sendServerMessage(sock, playerName + " has access level " + std::to_string(currentAccess));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't change the access level of someone with stronger privileges
|
|
||||||
// N.B. lower value = stronger privileges
|
|
||||||
if (currentAccess <= selfAccess) {
|
|
||||||
Chat::sendServerMessage(sock, "Can't change this player's access level (insufficient privileges)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int newAccess = std::strtol(args[2].c_str(), &tmp, 10);
|
|
||||||
if (*tmp) {
|
|
||||||
Chat::sendServerMessage(sock, "Invalid access level " + args[2]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can only assign an access level weaker than yours
|
|
||||||
if (newAccess <= selfAccess) {
|
|
||||||
Chat::sendServerMessage(sock, "Can only assign privileges weaker than your own");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
player->accountLevel = newAccess;
|
|
||||||
|
|
||||||
// Save to database
|
|
||||||
int accountId = Database::getAccountIdForPlayer(player->iID);
|
|
||||||
Database::updateAccountLevel(accountId, newAccess);
|
|
||||||
|
|
||||||
std::string msg = "Changed access level for " + playerName + " from " + std::to_string(currentAccess) + " to " + std::to_string(newAccess);
|
|
||||||
if (newAccess <= 50 && currentAccess > 50)
|
|
||||||
msg += " (they must log out and back in for some commands to be enabled)";
|
|
||||||
Chat::sendServerMessage(sock, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void populationCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
static void populationCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
@@ -1270,7 +1200,7 @@ static void registerCommand(std::string cmd, int requiredLevel, CommandHandler h
|
|||||||
|
|
||||||
void CustomCommands::init() {
|
void CustomCommands::init() {
|
||||||
registerCommand("help", 100, helpCommand, "list all unlocked server-side commands");
|
registerCommand("help", 100, helpCommand, "list all unlocked server-side commands");
|
||||||
registerCommand("access", 100, accessCommand, "check or change access levels");
|
registerCommand("access", 100, accessCommand, "print your access level");
|
||||||
registerCommand("instance", 30, instanceCommand, "print or change your current instance");
|
registerCommand("instance", 30, instanceCommand, "print or change your current instance");
|
||||||
registerCommand("mss", 30, mssCommand, "edit Monkey Skyway routes");
|
registerCommand("mss", 30, mssCommand, "edit Monkey Skyway routes");
|
||||||
registerCommand("npcr", 30, npcRotateCommand, "rotate NPCs");
|
registerCommand("npcr", 30, npcRotateCommand, "rotate NPCs");
|
||||||
|
|||||||
@@ -325,13 +325,6 @@ static void emailSend(CNSocket* sock, CNPacketData* data) {
|
|||||||
std::string logEmail = "[Email] " + PlayerManager::getPlayerName(plr, true) + " (to " + PlayerManager::getPlayerName(&otherPlr, true) + "): <" + email.SubjectLine + ">\n" + email.MsgBody;
|
std::string logEmail = "[Email] " + PlayerManager::getPlayerName(plr, true) + " (to " + PlayerManager::getPlayerName(&otherPlr, true) + "): <" + email.SubjectLine + ">\n" + email.MsgBody;
|
||||||
std::cout << logEmail << std::endl;
|
std::cout << logEmail << std::endl;
|
||||||
dump.push_back(logEmail);
|
dump.push_back(logEmail);
|
||||||
|
|
||||||
// notification to recipient if online
|
|
||||||
CNSocket* recipient = PlayerManager::getSockFromID(pkt->iTo_PCUID);
|
|
||||||
if (recipient != nullptr)
|
|
||||||
{
|
|
||||||
emailUpdateCheck(recipient, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Email::init() {
|
void Email::init() {
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ EntityRef::EntityRef(CNSocket *s) {
|
|||||||
EntityRef::EntityRef(int32_t i) {
|
EntityRef::EntityRef(int32_t i) {
|
||||||
id = i;
|
id = i;
|
||||||
|
|
||||||
kind = EntityKind::INVALID;
|
assert(NPCManager::NPCs.find(id) != NPCManager::NPCs.end());
|
||||||
if (NPCManager::NPCs.find(id) != NPCManager::NPCs.end())
|
kind = NPCManager::NPCs[id]->kind;
|
||||||
kind = NPCManager::NPCs[id]->kind;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityRef::isValid() const {
|
bool EntityRef::isValid() const {
|
||||||
|
|||||||
@@ -64,9 +64,6 @@ static void attachGroupData(std::vector<EntityRef>& pcs, std::vector<EntityRef>&
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Groups::addToGroup(Group* group, EntityRef member) {
|
void Groups::addToGroup(Group* group, EntityRef member) {
|
||||||
if (group == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (member.kind == EntityKind::PLAYER) {
|
if (member.kind == EntityKind::PLAYER) {
|
||||||
Player* plr = PlayerManager::getPlayer(member.sock);
|
Player* plr = PlayerManager::getPlayer(member.sock);
|
||||||
plr->group = group;
|
plr->group = group;
|
||||||
@@ -112,9 +109,6 @@ void Groups::addToGroup(Group* group, EntityRef member) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Groups::removeFromGroup(Group* group, EntityRef member) {
|
bool Groups::removeFromGroup(Group* group, EntityRef member) {
|
||||||
if (group == nullptr)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (member.kind == EntityKind::PLAYER) {
|
if (member.kind == EntityKind::PLAYER) {
|
||||||
Player* plr = PlayerManager::getPlayer(member.sock);
|
Player* plr = PlayerManager::getPlayer(member.sock);
|
||||||
plr->group = nullptr; // no dangling pointers here muahaahahah
|
plr->group = nullptr; // no dangling pointers here muahaahahah
|
||||||
@@ -174,9 +168,6 @@ bool Groups::removeFromGroup(Group* group, EntityRef member) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Groups::disbandGroup(Group* group) {
|
void Groups::disbandGroup(Group* group) {
|
||||||
if (group == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// remove everyone from the group!!
|
// remove everyone from the group!!
|
||||||
bool done = false;
|
bool done = false;
|
||||||
while(!done) {
|
while(!done) {
|
||||||
@@ -261,9 +252,6 @@ static void leaveGroup(CNSocket* sock, CNPacketData* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Groups::sendToGroup(Group* group, void* buf, uint32_t type, size_t size) {
|
void Groups::sendToGroup(Group* group, void* buf, uint32_t type, size_t size) {
|
||||||
if (group == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto players = group->filter(EntityKind::PLAYER);
|
auto players = group->filter(EntityKind::PLAYER);
|
||||||
for (EntityRef ref : players) {
|
for (EntityRef ref : players) {
|
||||||
ref.sock->sendPacket(buf, type, size);
|
ref.sock->sendPacket(buf, type, size);
|
||||||
@@ -271,9 +259,6 @@ void Groups::sendToGroup(Group* group, void* buf, uint32_t type, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Groups::sendToGroup(Group* group, EntityRef excluded, void* buf, uint32_t type, size_t size) {
|
void Groups::sendToGroup(Group* group, EntityRef excluded, void* buf, uint32_t type, size_t size) {
|
||||||
if (group == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto players = group->filter(EntityKind::PLAYER);
|
auto players = group->filter(EntityKind::PLAYER);
|
||||||
for (EntityRef ref : players) {
|
for (EntityRef ref : players) {
|
||||||
if(ref != excluded) ref.sock->sendPacket(buf, type, size);
|
if(ref != excluded) ref.sock->sendPacket(buf, type, size);
|
||||||
@@ -309,9 +294,6 @@ void Groups::groupTickInfo(CNSocket* sock) {
|
|||||||
|
|
||||||
void Groups::groupKick(Group* group, EntityRef ref) {
|
void Groups::groupKick(Group* group, EntityRef ref) {
|
||||||
|
|
||||||
if (group == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// if you are the group leader, destroy your own group and kick everybody
|
// if you are the group leader, destroy your own group and kick everybody
|
||||||
if (group->members[0] == ref) {
|
if (group->members[0] == ref) {
|
||||||
disbandGroup(group);
|
disbandGroup(group);
|
||||||
|
|||||||
@@ -416,9 +416,6 @@ static void itemDeleteHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
if (itemdel->iSlotNum < 0 || itemdel->iSlotNum >= AINVEN_COUNT)
|
|
||||||
return; // sanity check
|
|
||||||
|
|
||||||
resp.eIL = itemdel->eIL;
|
resp.eIL = itemdel->eIL;
|
||||||
resp.iSlotNum = itemdel->iSlotNum;
|
resp.iSlotNum = itemdel->iSlotNum;
|
||||||
|
|
||||||
|
|||||||
@@ -386,9 +386,6 @@ static void taskStart(CNSocket* sock, CNPacketData* data) {
|
|||||||
static void taskEnd(CNSocket* sock, CNPacketData* data) {
|
static void taskEnd(CNSocket* sock, CNPacketData* data) {
|
||||||
sP_CL2FE_REQ_PC_TASK_END* missionData = (sP_CL2FE_REQ_PC_TASK_END*)data->buf;
|
sP_CL2FE_REQ_PC_TASK_END* missionData = (sP_CL2FE_REQ_PC_TASK_END*)data->buf;
|
||||||
|
|
||||||
if (Missions::Tasks.find(missionData->iTaskNum) == Missions::Tasks.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
TaskData* task = Missions::Tasks[missionData->iTaskNum];
|
TaskData* task = Missions::Tasks[missionData->iTaskNum];
|
||||||
|
|
||||||
// handle timed mission failure
|
// handle timed mission failure
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ void Nanos::summonNano(CNSocket *sock, int slot, bool silent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void setNanoSkill(CNSocket* sock, sP_CL2FE_REQ_NANO_TUNE* skill) {
|
static void setNanoSkill(CNSocket* sock, sP_CL2FE_REQ_NANO_TUNE* skill) {
|
||||||
if (skill == nullptr || skill->iNanoID >= NANO_COUNT || skill->iNanoID < 0)
|
if (skill->iNanoID >= NANO_COUNT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Player *plr = PlayerManager::getPlayer(sock);
|
Player *plr = PlayerManager::getPlayer(sock);
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ struct Player : public Entity, public ICombatant {
|
|||||||
bool notify = false;
|
bool notify = false;
|
||||||
bool hidden = false;
|
bool hidden = false;
|
||||||
bool unwarpable = false;
|
bool unwarpable = false;
|
||||||
bool initialLoadDone = false;
|
|
||||||
|
|
||||||
|
bool buddiesSynced = false;
|
||||||
int64_t buddyIDs[50] = {};
|
int64_t buddyIDs[50] = {};
|
||||||
bool isBuddyBlocked[50] = {};
|
bool isBuddyBlocked[50] = {};
|
||||||
|
|
||||||
|
|||||||
@@ -155,21 +155,16 @@ void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) {
|
|||||||
* Nanos the player hasn't unlocked will (and should) be greyed out. Thus, all nanos should be accounted
|
* Nanos the player hasn't unlocked will (and should) be greyed out. Thus, all nanos should be accounted
|
||||||
* for in these packets, even if the player hasn't unlocked them.
|
* for in these packets, even if the player hasn't unlocked them.
|
||||||
*/
|
*/
|
||||||
static void sendNanoBook(CNSocket *sock, Player *plr, bool resizeOnly) {
|
static void sendNanoBookSubset(CNSocket *sock) {
|
||||||
#ifdef ACADEMY
|
#ifdef ACADEMY
|
||||||
|
Player *plr = getPlayer(sock);
|
||||||
|
|
||||||
int16_t id = 0;
|
int16_t id = 0;
|
||||||
INITSTRUCT(sP_FE2CL_REP_NANO_BOOK_SUBSET, pkt);
|
INITSTRUCT(sP_FE2CL_REP_NANO_BOOK_SUBSET, pkt);
|
||||||
|
|
||||||
pkt.PCUID = plr->iID;
|
pkt.PCUID = plr->iID;
|
||||||
pkt.bookSize = NANO_COUNT;
|
pkt.bookSize = NANO_COUNT;
|
||||||
|
|
||||||
if (resizeOnly) {
|
|
||||||
// triggers nano array resizing without
|
|
||||||
// actually sending nanos
|
|
||||||
sock->sendPacket(pkt, P_FE2CL_REP_NANO_BOOK_SUBSET);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (id < NANO_COUNT) {
|
while (id < NANO_COUNT) {
|
||||||
pkt.elementOffset = id;
|
pkt.elementOffset = id;
|
||||||
|
|
||||||
@@ -217,7 +212,6 @@ static void enterPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
response.iID = plr->iID;
|
response.iID = plr->iID;
|
||||||
response.uiSvrTime = getTime();
|
response.uiSvrTime = getTime();
|
||||||
|
|
||||||
response.PCLoadData2CL.iUserLevel = plr->accountLevel;
|
response.PCLoadData2CL.iUserLevel = plr->accountLevel;
|
||||||
response.PCLoadData2CL.iHP = plr->HP;
|
response.PCLoadData2CL.iHP = plr->HP;
|
||||||
response.PCLoadData2CL.iLevel = plr->level;
|
response.PCLoadData2CL.iLevel = plr->level;
|
||||||
@@ -300,21 +294,27 @@ static void enterPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
sock->setFEKey(lm->FEKey);
|
sock->setFEKey(lm->FEKey);
|
||||||
sock->setActiveKey(SOCKETKEY_FE); // send all packets using the FE key from now on
|
sock->setActiveKey(SOCKETKEY_FE); // send all packets using the FE key from now on
|
||||||
|
|
||||||
// Academy builds receive nanos in a separate packet. An initial one with the size of the
|
|
||||||
// nano book needs to be sent before PC_ENTER_SUCC so the client can resize its nano arrays,
|
|
||||||
// and then proper packets with the nanos included must be sent after, while the game is loading.
|
|
||||||
sendNanoBook(sock, plr, true);
|
|
||||||
|
|
||||||
sock->sendPacket(response, P_FE2CL_REP_PC_ENTER_SUCC);
|
sock->sendPacket(response, P_FE2CL_REP_PC_ENTER_SUCC);
|
||||||
|
|
||||||
sendNanoBook(sock, plr, false);
|
// transmit MOTD after entering the game, so the client hopefully changes modes on time
|
||||||
|
Chat::sendServerMessage(sock, settings::MOTDSTRING);
|
||||||
|
|
||||||
// transfer ownership of Player object into the shard (still valid in this function though)
|
// transfer ownership of Player object into the shard (still valid in this function though)
|
||||||
addPlayer(sock, plr);
|
addPlayer(sock, plr);
|
||||||
|
|
||||||
|
// check if there is an expiring vehicle
|
||||||
|
Items::checkItemExpire(sock, plr);
|
||||||
|
|
||||||
// set player equip stats
|
// set player equip stats
|
||||||
Items::setItemStats(plr);
|
Items::setItemStats(plr);
|
||||||
|
|
||||||
|
Missions::failInstancedMissions(sock);
|
||||||
|
|
||||||
|
sendNanoBookSubset(sock);
|
||||||
|
|
||||||
|
// initial buddy sync
|
||||||
|
Buddies::refreshBuddyList(sock);
|
||||||
|
|
||||||
for (auto& pair : players)
|
for (auto& pair : players)
|
||||||
if (pair.second->notify)
|
if (pair.second->notify)
|
||||||
Chat::sendServerMessage(pair.first, "[ADMIN]" + getPlayerName(plr) + " has joined.");
|
Chat::sendServerMessage(pair.first, "[ADMIN]" + getPlayerName(plr) + " has joined.");
|
||||||
@@ -377,17 +377,6 @@ static void loadPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
sock->sendPacket(pkt, P_FE2CL_INSTANCE_MAP_INFO);
|
sock->sendPacket(pkt, P_FE2CL_INSTANCE_MAP_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!plr->initialLoadDone) {
|
|
||||||
// these should be called only once, but not until after
|
|
||||||
// first load-in or else the client may ignore the packets
|
|
||||||
Chat::sendServerMessage(sock, settings::MOTDSTRING); // MOTD
|
|
||||||
Missions::failInstancedMissions(sock); // auto-fail missions
|
|
||||||
Buddies::sendBuddyList(sock); // buddy list
|
|
||||||
Items::checkItemExpire(sock, plr); // vehicle expiration
|
|
||||||
|
|
||||||
plr->initialLoadDone = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heartbeatPlayer(CNSocket* sock, CNPacketData* data) {
|
static void heartbeatPlayer(CNSocket* sock, CNPacketData* data) {
|
||||||
|
|||||||
@@ -106,11 +106,10 @@ static void racingEnd(CNSocket* sock, CNPacketData* data) {
|
|||||||
int timeDiff = now - epRace.startTime;
|
int timeDiff = now - epRace.startTime;
|
||||||
int podsCollected = epRace.collectedRings.size();
|
int podsCollected = epRace.collectedRings.size();
|
||||||
|
|
||||||
int score = std::exp(
|
int score = std::min(epInfo.maxScore, (int)std::exp(
|
||||||
(epInfo.podFactor * podsCollected) / epInfo.maxPods
|
(epInfo.podFactor * podsCollected) / epInfo.maxPods
|
||||||
- (epInfo.timeFactor * timeDiff) / epInfo.maxTime
|
- (epInfo.timeFactor * timeDiff) / epInfo.maxTime
|
||||||
+ epInfo.scaleFactor);
|
+ epInfo.scaleFactor));
|
||||||
score = (settings::IZRACESCORECAPPED && score > epInfo.maxScore) ? epInfo.maxScore : score;
|
|
||||||
int fm = (1.0 + std::exp(epInfo.scaleFactor - 1.0) * epInfo.podFactor * podsCollected) / epInfo.maxPods;
|
int fm = (1.0 + std::exp(epInfo.scaleFactor - 1.0) * epInfo.podFactor * podsCollected) / epInfo.maxPods;
|
||||||
|
|
||||||
// we submit the ranking first...
|
// we submit the ranking first...
|
||||||
@@ -133,9 +132,8 @@ static void racingEnd(CNSocket* sock, CNPacketData* data) {
|
|||||||
std::vector<int>* rankRewards = &EPRewards[epInfo.EPID].second;
|
std::vector<int>* rankRewards = &EPRewards[epInfo.EPID].second;
|
||||||
|
|
||||||
// top ranking
|
// top ranking
|
||||||
int maxRank = rankScores->size() - 1;
|
|
||||||
int topRank = 0;
|
int topRank = 0;
|
||||||
while (topRank < maxRank && rankScores->at(topRank) > topRankingPlayer.Score)
|
while (rankScores->at(topRank) > topRankingPlayer.Score)
|
||||||
topRank++;
|
topRank++;
|
||||||
|
|
||||||
resp.iEPTopRank = topRank + 1;
|
resp.iEPTopRank = topRank + 1;
|
||||||
@@ -145,7 +143,7 @@ static void racingEnd(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
// this ranking
|
// this ranking
|
||||||
int rank = 0;
|
int rank = 0;
|
||||||
while (rank < maxRank && rankScores->at(rank) > postRanking.Score)
|
while (rankScores->at(rank) > postRanking.Score)
|
||||||
rank++;
|
rank++;
|
||||||
|
|
||||||
resp.iEPRank = rank + 1;
|
resp.iEPRank = rank + 1;
|
||||||
|
|||||||
@@ -610,7 +610,7 @@ static void loadDrops(json& dropData) {
|
|||||||
|
|
||||||
if (rankScores.size() != 5 || rankScores.size() != rankRewards.size()) {
|
if (rankScores.size() != 5 || rankScores.size() != rankRewards.size()) {
|
||||||
char buff[255];
|
char buff[255];
|
||||||
snprintf(buff, 255, "Race in EP %d doesn't have exactly 5 score/reward pairs", raceEPID);
|
sprintf(buff, "Race in EP %d doesn't have exactly 5 score/reward pairs", raceEPID);
|
||||||
throw TableException(std::string(buff));
|
throw TableException(std::string(buff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,36 +186,6 @@ static void tradeOfferRefusal(CNSocket* sock, CNPacketData* data) {
|
|||||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL));
|
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_REFUSAL, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_REFUSAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tradeOfferCancel(CNSocket* sock, CNPacketData* data) {
|
|
||||||
sP_CL2FE_REQ_PC_TRADE_OFFER_CANCEL* pacdat = (sP_CL2FE_REQ_PC_TRADE_OFFER_CANCEL*)data->buf;
|
|
||||||
|
|
||||||
CNSocket* otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
|
||||||
|
|
||||||
if (otherSock == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER_CANCEL, resp);
|
|
||||||
resp.iID_Request = pacdat->iID_Request;
|
|
||||||
resp.iID_From = pacdat->iID_From;
|
|
||||||
resp.iID_To = pacdat->iID_To;
|
|
||||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_CANCEL, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_CANCEL));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tradeOfferAbort(CNSocket* sock, CNPacketData* data) {
|
|
||||||
sP_CL2FE_REQ_PC_TRADE_OFFER_ABORT* pacdat = (sP_CL2FE_REQ_PC_TRADE_OFFER_ABORT*)data->buf;
|
|
||||||
|
|
||||||
CNSocket* otherSock = PlayerManager::getSockFromID(pacdat->iID_From);
|
|
||||||
|
|
||||||
if (otherSock == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_TRADE_OFFER_ABORT, resp);
|
|
||||||
resp.iID_Request = pacdat->iID_Request;
|
|
||||||
resp.iID_From = pacdat->iID_From;
|
|
||||||
resp.iID_To = pacdat->iID_To;
|
|
||||||
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_PC_TRADE_OFFER_ABORT, sizeof(sP_FE2CL_REP_PC_TRADE_OFFER_ABORT));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tradeConfirm(CNSocket* sock, CNPacketData* data) {
|
static void tradeConfirm(CNSocket* sock, CNPacketData* data) {
|
||||||
sP_CL2FE_REQ_PC_TRADE_CONFIRM* pacdat = (sP_CL2FE_REQ_PC_TRADE_CONFIRM*)data->buf;
|
sP_CL2FE_REQ_PC_TRADE_CONFIRM* pacdat = (sP_CL2FE_REQ_PC_TRADE_CONFIRM*)data->buf;
|
||||||
|
|
||||||
@@ -460,8 +430,6 @@ void Trading::init() {
|
|||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER, tradeOffer);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER, tradeOffer);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_ACCEPT, tradeOfferAccept);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_ACCEPT, tradeOfferAccept);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL, tradeOfferRefusal);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_REFUSAL, tradeOfferRefusal);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_CANCEL, tradeOfferCancel);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_OFFER_ABORT, tradeOfferAbort);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CONFIRM, tradeConfirm);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CONFIRM, tradeConfirm);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CONFIRM_CANCEL, tradeConfirmCancel);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_CONFIRM_CANCEL, tradeConfirmCancel);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_ITEM_REGISTER, tradeRegisterItem);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_TRADE_ITEM_REGISTER, tradeRegisterItem);
|
||||||
|
|||||||
@@ -50,15 +50,13 @@ time_t getTime();
|
|||||||
time_t getTimestamp();
|
time_t getTimestamp();
|
||||||
void terminate(int);
|
void terminate(int);
|
||||||
|
|
||||||
// The PROTOCOL_VERSION definition can be defined by the build system.
|
// The PROTOCOL_VERSION definition is defined by the build system.
|
||||||
#if !defined(PROTOCOL_VERSION)
|
#if !defined(PROTOCOL_VERSION)
|
||||||
#define PROTOCOL_VERSION 104
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PROTOCOL_VERSION == 104
|
|
||||||
#include "structs/0104.hpp"
|
#include "structs/0104.hpp"
|
||||||
#elif PROTOCOL_VERSION == 728
|
#elif PROTOCOL_VERSION == 728
|
||||||
#include "structs/0728.hpp"
|
#include "structs/0728.hpp"
|
||||||
|
#elif PROTOCOL_VERSION == 104
|
||||||
|
#include "structs/0104.hpp"
|
||||||
#elif PROTOCOL_VERSION == 1013
|
#elif PROTOCOL_VERSION == 1013
|
||||||
#include "structs/1013.hpp"
|
#include "structs/1013.hpp"
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -46,13 +46,9 @@ namespace Database {
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
void findAccount(Account* account, std::string login);
|
void findAccount(Account* account, std::string login);
|
||||||
|
// returns ID, 0 if something failed
|
||||||
// return ID, 0 if something failed
|
|
||||||
int getAccountIdForPlayer(int playerId);
|
|
||||||
int addAccount(std::string login, std::string password);
|
int addAccount(std::string login, std::string password);
|
||||||
|
|
||||||
void updateAccountLevel(int accountId, int accountLevel);
|
|
||||||
|
|
||||||
// interface for the /ban command
|
// interface for the /ban command
|
||||||
bool banPlayer(int playerId, std::string& reason);
|
bool banPlayer(int playerId, std::string& reason);
|
||||||
bool unbanPlayer(int playerId);
|
bool unbanPlayer(int playerId);
|
||||||
|
|||||||
@@ -226,11 +226,10 @@ static void createTables() {
|
|||||||
static int getTableSize(std::string tableName) {
|
static int getTableSize(std::string tableName) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit); // XXX
|
std::lock_guard<std::mutex> lock(dbCrit); // XXX
|
||||||
|
|
||||||
// you aren't allowed to bind the table name
|
const char* sql = "SELECT COUNT(*) FROM ?";
|
||||||
const char* sql = "SELECT COUNT(*) FROM ";
|
|
||||||
tableName.insert(0, sql);
|
|
||||||
sqlite3_stmt* stmt;
|
sqlite3_stmt* stmt;
|
||||||
sqlite3_prepare_v2(db, tableName.c_str(), -1, &stmt, NULL);
|
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||||
|
sqlite3_bind_text(stmt, 1, tableName.c_str(), -1, NULL);
|
||||||
sqlite3_step(stmt);
|
sqlite3_step(stmt);
|
||||||
int result = sqlite3_column_int(stmt, 0);
|
int result = sqlite3_column_int(stmt, 0);
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
@@ -267,17 +266,17 @@ void Database::open() {
|
|||||||
checkMetaTable();
|
checkMetaTable();
|
||||||
createTables();
|
createTables();
|
||||||
|
|
||||||
std::cout << "[INFO] Database in operation";
|
std::cout << "[INFO] Database in operation ";
|
||||||
int accounts = getTableSize("Accounts");
|
int accounts = getTableSize("Accounts");
|
||||||
int players = getTableSize("Players");
|
int players = getTableSize("Players");
|
||||||
std::string message = "";
|
std::string message = "";
|
||||||
if (accounts > 0) {
|
if (accounts > 0) {
|
||||||
message += ": Found " + std::to_string(accounts) + " account";
|
message += ": Found " + std::to_string(accounts) + " Account";
|
||||||
if (accounts > 1)
|
if (accounts > 1)
|
||||||
message += "s";
|
message += "s";
|
||||||
}
|
}
|
||||||
if (players > 0) {
|
if (players > 0) {
|
||||||
message += " and " + std::to_string(players) + " player";
|
message += " and " + std::to_string(players) + " Player Character";
|
||||||
if (players > 1)
|
if (players > 1)
|
||||||
message += "s";
|
message += "s";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,32 +27,6 @@ void Database::findAccount(Account* account, std::string login) {
|
|||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::getAccountIdForPlayer(int playerId) {
|
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
|
||||||
|
|
||||||
const char* sql = R"(
|
|
||||||
SELECT AccountID
|
|
||||||
FROM Players
|
|
||||||
WHERE PlayerID = ?
|
|
||||||
LIMIT 1;
|
|
||||||
)";
|
|
||||||
sqlite3_stmt* stmt;
|
|
||||||
|
|
||||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
|
||||||
sqlite3_bind_int(stmt, 1, playerId);
|
|
||||||
|
|
||||||
int rc = sqlite3_step(stmt);
|
|
||||||
if (rc != SQLITE_ROW) {
|
|
||||||
std::cout << "[WARN] Database: couldn't get account id for player " << playerId << std::endl;
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int accountId = sqlite3_column_int(stmt, 0);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
return accountId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Database::addAccount(std::string login, std::string password) {
|
int Database::addAccount(std::string login, std::string password) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
@@ -78,26 +52,6 @@ int Database::addAccount(std::string login, std::string password) {
|
|||||||
return sqlite3_last_insert_rowid(db);
|
return sqlite3_last_insert_rowid(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::updateAccountLevel(int accountId, int accountLevel) {
|
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
|
||||||
|
|
||||||
const char* sql = R"(
|
|
||||||
UPDATE Accounts SET
|
|
||||||
AccountLevel = ?
|
|
||||||
WHERE AccountID = ?;
|
|
||||||
)";
|
|
||||||
sqlite3_stmt* stmt;
|
|
||||||
|
|
||||||
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
|
||||||
sqlite3_bind_int(stmt, 1, accountLevel);
|
|
||||||
sqlite3_bind_int(stmt, 2, accountId);
|
|
||||||
|
|
||||||
int rc = sqlite3_step(stmt);
|
|
||||||
if (rc != SQLITE_DONE)
|
|
||||||
std::cout << "[WARN] Database fail on updateAccountLevel(): " << sqlite3_errmsg(db) << std::endl;
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::updateSelected(int accountId, int slot) {
|
void Database::updateSelected(int accountId, int slot) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
std::lock_guard<std::mutex> lock(dbCrit);
|
||||||
|
|
||||||
|
|||||||
@@ -208,8 +208,6 @@ void Database::addBlock(int playerId, int blockedPlayerId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Database::removeBlock(int playerId, int blockedPlayerId) {
|
void Database::removeBlock(int playerId, int blockedPlayerId) {
|
||||||
std::lock_guard<std::mutex> lock(dbCrit);
|
|
||||||
|
|
||||||
const char* sql = R"(
|
const char* sql = R"(
|
||||||
DELETE FROM Blocks
|
DELETE FROM Blocks
|
||||||
WHERE PlayerID = ? AND BlockedPlayerID = ?;
|
WHERE PlayerID = ? AND BlockedPlayerID = ?;
|
||||||
|
|||||||
30
src/lua/Manager.cpp
Normal file
30
src/lua/Manager.cpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#include "lua/Manager.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace LuaManager;
|
||||||
|
|
||||||
|
static lua_State *globalState = nullptr;
|
||||||
|
|
||||||
|
void LuaManager::init() {
|
||||||
|
lua_State *L = luaL_newstate();
|
||||||
|
luaL_openlibs(L);
|
||||||
|
|
||||||
|
static LuaThread *startScript(const char *script) {
|
||||||
|
lua_State *L = lua_newthread(globalState);
|
||||||
|
LuaThread *T = new LuaThread(L, luaL_ref(L, LUA_REGISTRYINDEX));
|
||||||
|
|
||||||
|
if (luaL_dostring(L, script)) {
|
||||||
|
std::cout << "Lua error: " << lua_tostring(L, -1) << std::endl;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaManager::init() {
|
||||||
|
globalState = luaL_newstate();
|
||||||
|
luaL_openlibs(globalState);
|
||||||
|
|
||||||
|
delete startScript("print(\"Hello from Lua!\")");
|
||||||
|
}
|
||||||
7
src/lua/Manager.hpp
Normal file
7
src/lua/Manager.hpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "lua/Thread.hpp"
|
||||||
|
|
||||||
|
namespace LuaManager {
|
||||||
|
void init();
|
||||||
|
}
|
||||||
17
src/lua/Thread.hpp
Normal file
17
src/lua/Thread.hpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "lua.h"
|
||||||
|
#include "lualib.h"
|
||||||
|
#include "lauxlib.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LuaThread {
|
||||||
|
lua_State *L;
|
||||||
|
int ref;
|
||||||
|
|
||||||
|
LuaThread(lua_State *L, int ref) : L(L), ref(ref) {}
|
||||||
|
~LuaThread() {
|
||||||
|
luaL_unref(L, LUA_REGISTRYINDEX, ref);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -24,6 +24,8 @@
|
|||||||
#include "Eggs.hpp"
|
#include "Eggs.hpp"
|
||||||
#include "Rand.hpp"
|
#include "Rand.hpp"
|
||||||
|
|
||||||
|
#include "lua/Manager.hpp"
|
||||||
|
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "sandbox/Sandbox.hpp"
|
#include "sandbox/Sandbox.hpp"
|
||||||
|
|
||||||
@@ -138,6 +140,7 @@ int main() {
|
|||||||
Trading::init();
|
Trading::init();
|
||||||
|
|
||||||
Database::open();
|
Database::open();
|
||||||
|
LuaManager::init();
|
||||||
|
|
||||||
switch (settings::EVENTMODE) {
|
switch (settings::EVENTMODE) {
|
||||||
case 0: break; // no event
|
case 0: break; // no event
|
||||||
|
|||||||
@@ -67,9 +67,6 @@ int settings::MONITORINTERVAL = 5000;
|
|||||||
// event mode settings
|
// event mode settings
|
||||||
int settings::EVENTMODE = 0;
|
int settings::EVENTMODE = 0;
|
||||||
|
|
||||||
// race settings
|
|
||||||
bool settings::IZRACESCORECAPPED = true;
|
|
||||||
|
|
||||||
void settings::init() {
|
void settings::init() {
|
||||||
INIReader reader("config.ini");
|
INIReader reader("config.ini");
|
||||||
|
|
||||||
@@ -114,7 +111,6 @@ void settings::init() {
|
|||||||
EVENTMODE = reader.GetInteger("shard", "eventmode", EVENTMODE);
|
EVENTMODE = reader.GetInteger("shard", "eventmode", EVENTMODE);
|
||||||
DISABLEFIRSTUSEFLAG = reader.GetBoolean("shard", "disablefirstuseflag", DISABLEFIRSTUSEFLAG);
|
DISABLEFIRSTUSEFLAG = reader.GetBoolean("shard", "disablefirstuseflag", DISABLEFIRSTUSEFLAG);
|
||||||
ANTICHEAT = reader.GetBoolean("shard", "anticheat", ANTICHEAT);
|
ANTICHEAT = reader.GetBoolean("shard", "anticheat", ANTICHEAT);
|
||||||
IZRACESCORECAPPED = reader.GetBoolean("shard", "izracescorecapped", IZRACESCORECAPPED);
|
|
||||||
MONITORENABLED = reader.GetBoolean("monitor", "enabled", MONITORENABLED);
|
MONITORENABLED = reader.GetBoolean("monitor", "enabled", MONITORENABLED);
|
||||||
MONITORPORT = reader.GetInteger("monitor", "port", MONITORPORT);
|
MONITORPORT = reader.GetInteger("monitor", "port", MONITORPORT);
|
||||||
MONITORINTERVAL = reader.GetInteger("monitor", "interval", MONITORINTERVAL);
|
MONITORINTERVAL = reader.GetInteger("monitor", "interval", MONITORINTERVAL);
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ namespace settings {
|
|||||||
extern int MONITORPORT;
|
extern int MONITORPORT;
|
||||||
extern int MONITORINTERVAL;
|
extern int MONITORINTERVAL;
|
||||||
extern bool DISABLEFIRSTUSEFLAG;
|
extern bool DISABLEFIRSTUSEFLAG;
|
||||||
extern bool IZRACESCORECAPPED;
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
}
|
}
|
||||||
|
|||||||
14842
vendor/JSON.hpp
vendored
14842
vendor/JSON.hpp
vendored
File diff suppressed because it is too large
Load Diff
1
vendor/Lua
vendored
Submodule
1
vendor/Lua
vendored
Submodule
Submodule vendor/Lua added at 88246d621a
8
vendor/bcrypt/bcrypt.c
vendored
8
vendor/bcrypt/bcrypt.c
vendored
@@ -22,13 +22,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#ifdef _WIN32 || _WIN64
|
||||||
// On windows we need to generate random bytes differently.
|
// On windows we need to generate random bytes differently.
|
||||||
#if defined(_WIN32) && !defined(_WIN64)
|
|
||||||
typedef __int32 ssize_t;
|
|
||||||
#elif defined(_WIN32) && defined(_WIN64)
|
|
||||||
typedef __int64 ssize_t;
|
typedef __int64 ssize_t;
|
||||||
#endif
|
|
||||||
#define BCRYPT_HASHSIZE 60
|
#define BCRYPT_HASHSIZE 60
|
||||||
|
|
||||||
#include "bcrypt.h"
|
#include "bcrypt.h"
|
||||||
@@ -121,7 +117,7 @@ int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE])
|
|||||||
char *aux;
|
char *aux;
|
||||||
|
|
||||||
// Note: Windows does not have /dev/urandom sadly.
|
// Note: Windows does not have /dev/urandom sadly.
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#ifdef _WIN32 || _WIN64
|
||||||
HCRYPTPROV p;
|
HCRYPTPROV p;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
|
|||||||
2
vendor/bcrypt/crypt_blowfish.c
vendored
2
vendor/bcrypt/crypt_blowfish.c
vendored
@@ -51,7 +51,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Just to make sure the prototypes match the actual definitions */
|
/* Just to make sure the prototypes match the actual definitions */
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#ifdef _WIN32 || _WIN64
|
||||||
#include "crypt_blowfish.h"
|
#include "crypt_blowfish.h"
|
||||||
#else
|
#else
|
||||||
#include "crypt_blowfish.h"
|
#include "crypt_blowfish.h"
|
||||||
|
|||||||
4
vendor/bcrypt/wrapper.c
vendored
4
vendor/bcrypt/wrapper.c
vendored
@@ -41,7 +41,7 @@
|
|||||||
#define __SKIP_GNU
|
#define __SKIP_GNU
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#ifdef _WIN32 | _WIN64
|
||||||
#include "ow-crypt.h"
|
#include "ow-crypt.h"
|
||||||
|
|
||||||
#include "crypt_blowfish.h"
|
#include "crypt_blowfish.h"
|
||||||
@@ -251,7 +251,7 @@ char *__crypt_gensalt_ra(const char *prefix, unsigned long count,
|
|||||||
input, size, output, sizeof(output));
|
input, size, output, sizeof(output));
|
||||||
|
|
||||||
if (retval) {
|
if (retval) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#ifdef _WIN32 | _WIN64
|
||||||
retval = _strdup(retval);
|
retval = _strdup(retval);
|
||||||
#else
|
#else
|
||||||
retval = strdup(retval);
|
retval = strdup(retval);
|
||||||
|
|||||||
Reference in New Issue
Block a user