11 Commits

Author SHA1 Message Date
CakeLancelot
fa8c1e73d1 Fix a few compiler warnings and formatting for DB startup message (#272)
Note that the warning in TableData.cpp only seems to occur on clang (deprecated-declarations)

Database account/player count message:
Before: [INFO] Database in operation : Found 1 account(s) and 2 player(s)s
After: [INFO] Database in operation: Found 1 account and 2 players
2024-03-31 13:02:39 -05:00
CakeLancelot
aeac57ebf7 Remove duplicate headers from Makefile 2024-03-31 02:48:18 -05:00
CakeLancelot
632406e93b Bump nlohmann JSON to 3.11.3 (#271)
I've checked all the changelogs from the version we were using (3.9.1) to the latest, and there should not be any breaking changes or deprecated functionality.
The server also compiled fine and I did not encounter any issues after a brief play session.
2024-03-29 21:50:55 -05:00
837f109752 Add missing mutex 2024-02-03 03:13:43 -05:00
c11cfebdb1 Fix account and player counts on startup 2024-02-03 03:13:24 -05:00
20367d77f0 Bump copyright date 2024-02-02 22:01:38 -05:00
8d04f31c61 Default PROTOCOL_VERSION to 104 2024-02-02 21:58:37 -05:00
FinnHornhoover
44560a46b7 Rank Calculation Out-of-Bounds Fix (#268) 2023-12-24 02:49:51 +01:00
gsemaj
21d280147c Shard crash fixes 2023-12-19 13:23:58 -05:00
FinnHornhoover
b765821552 added option to disable score capping 2023-12-19 13:18:43 -05:00
e61682dfb2 fix: out-of-bounds index in itemDeleteHandler() 2023-12-18 04:41:53 -06:00
19 changed files with 7144 additions and 7786 deletions

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020-2023 OpenFusion Contributors
Copyright (c) 2020-2024 OpenFusion Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -95,8 +95,6 @@ CXXHDR=\
vendor/bcrypt/BCrypt.hpp\
vendor/INIReader.hpp\
vendor/JSON.hpp\
vendor/INIReader.hpp\
vendor/JSON.hpp\
src/Buffs.hpp\
src/Chat.hpp\
src/CustomCommands.hpp\

View File

@@ -66,6 +66,9 @@ motd=Welcome to OpenFusion!
# location of the database
#dbpath=database.db
# should there be a score cap for infected zone races?
#izracescorecapped=true
# should tutorial flags be disabled off the bat?
disablefirstuseflag=true

View File

@@ -16,8 +16,9 @@ EntityRef::EntityRef(CNSocket *s) {
EntityRef::EntityRef(int32_t i) {
id = i;
assert(NPCManager::NPCs.find(id) != NPCManager::NPCs.end());
kind = NPCManager::NPCs[id]->kind;
kind = EntityKind::INVALID;
if (NPCManager::NPCs.find(id) != NPCManager::NPCs.end())
kind = NPCManager::NPCs[id]->kind;
}
bool EntityRef::isValid() const {

View File

@@ -64,6 +64,9 @@ static void attachGroupData(std::vector<EntityRef>& pcs, std::vector<EntityRef>&
}
void Groups::addToGroup(Group* group, EntityRef member) {
if (group == nullptr)
return;
if (member.kind == EntityKind::PLAYER) {
Player* plr = PlayerManager::getPlayer(member.sock);
plr->group = group;
@@ -109,6 +112,9 @@ void Groups::addToGroup(Group* group, EntityRef member) {
}
bool Groups::removeFromGroup(Group* group, EntityRef member) {
if (group == nullptr)
return false;
if (member.kind == EntityKind::PLAYER) {
Player* plr = PlayerManager::getPlayer(member.sock);
plr->group = nullptr; // no dangling pointers here muahaahahah
@@ -168,6 +174,9 @@ bool Groups::removeFromGroup(Group* group, EntityRef member) {
}
void Groups::disbandGroup(Group* group) {
if (group == nullptr)
return;
// remove everyone from the group!!
bool done = false;
while(!done) {
@@ -252,6 +261,9 @@ static void leaveGroup(CNSocket* sock, CNPacketData* data) {
}
void Groups::sendToGroup(Group* group, void* buf, uint32_t type, size_t size) {
if (group == nullptr)
return;
auto players = group->filter(EntityKind::PLAYER);
for (EntityRef ref : players) {
ref.sock->sendPacket(buf, type, size);
@@ -259,6 +271,9 @@ 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) {
if (group == nullptr)
return;
auto players = group->filter(EntityKind::PLAYER);
for (EntityRef ref : players) {
if(ref != excluded) ref.sock->sendPacket(buf, type, size);
@@ -294,6 +309,9 @@ void Groups::groupTickInfo(CNSocket* sock) {
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 (group->members[0] == ref) {
disbandGroup(group);

View File

@@ -416,6 +416,9 @@ static void itemDeleteHandler(CNSocket* sock, CNPacketData* data) {
Player* plr = PlayerManager::getPlayer(sock);
if (itemdel->iSlotNum < 0 || itemdel->iSlotNum >= AINVEN_COUNT)
return; // sanity check
resp.eIL = itemdel->eIL;
resp.iSlotNum = itemdel->iSlotNum;

View File

@@ -386,6 +386,9 @@ static void taskStart(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;
if (Missions::Tasks.find(missionData->iTaskNum) == Missions::Tasks.end())
return;
TaskData* task = Missions::Tasks[missionData->iTaskNum];
// handle timed mission failure

View File

@@ -110,7 +110,7 @@ void Nanos::summonNano(CNSocket *sock, int slot, bool silent) {
}
static void setNanoSkill(CNSocket* sock, sP_CL2FE_REQ_NANO_TUNE* skill) {
if (skill->iNanoID >= NANO_COUNT)
if (skill == nullptr || skill->iNanoID >= NANO_COUNT || skill->iNanoID < 0)
return;
Player *plr = PlayerManager::getPlayer(sock);

View File

@@ -106,10 +106,11 @@ static void racingEnd(CNSocket* sock, CNPacketData* data) {
int timeDiff = now - epRace.startTime;
int podsCollected = epRace.collectedRings.size();
int score = std::min(epInfo.maxScore, (int)std::exp(
int score = std::exp(
(epInfo.podFactor * podsCollected) / epInfo.maxPods
- (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;
// we submit the ranking first...
@@ -132,8 +133,9 @@ static void racingEnd(CNSocket* sock, CNPacketData* data) {
std::vector<int>* rankRewards = &EPRewards[epInfo.EPID].second;
// top ranking
int maxRank = rankScores->size() - 1;
int topRank = 0;
while (rankScores->at(topRank) > topRankingPlayer.Score)
while (topRank < maxRank && rankScores->at(topRank) > topRankingPlayer.Score)
topRank++;
resp.iEPTopRank = topRank + 1;
@@ -143,7 +145,7 @@ static void racingEnd(CNSocket* sock, CNPacketData* data) {
// this ranking
int rank = 0;
while (rankScores->at(rank) > postRanking.Score)
while (rank < maxRank && rankScores->at(rank) > postRanking.Score)
rank++;
resp.iEPRank = rank + 1;

View File

@@ -610,7 +610,7 @@ static void loadDrops(json& dropData) {
if (rankScores.size() != 5 || rankScores.size() != rankRewards.size()) {
char buff[255];
sprintf(buff, "Race in EP %d doesn't have exactly 5 score/reward pairs", raceEPID);
snprintf(buff, 255, "Race in EP %d doesn't have exactly 5 score/reward pairs", raceEPID);
throw TableException(std::string(buff));
}

View File

@@ -50,13 +50,15 @@ time_t getTime();
time_t getTimestamp();
void terminate(int);
// The PROTOCOL_VERSION definition is defined by the build system.
// The PROTOCOL_VERSION definition can be defined by the build system.
#if !defined(PROTOCOL_VERSION)
#define PROTOCOL_VERSION 104
#endif
#if PROTOCOL_VERSION == 104
#include "structs/0104.hpp"
#elif PROTOCOL_VERSION == 728
#include "structs/0728.hpp"
#elif PROTOCOL_VERSION == 104
#include "structs/0104.hpp"
#elif PROTOCOL_VERSION == 1013
#include "structs/1013.hpp"
#else

View File

@@ -226,10 +226,11 @@ static void createTables() {
static int getTableSize(std::string tableName) {
std::lock_guard<std::mutex> lock(dbCrit); // XXX
const char* sql = "SELECT COUNT(*) FROM ?";
// you aren't allowed to bind the table name
const char* sql = "SELECT COUNT(*) FROM ";
tableName.insert(0, sql);
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, tableName.c_str(), -1, NULL);
sqlite3_prepare_v2(db, tableName.c_str(), -1, &stmt, NULL);
sqlite3_step(stmt);
int result = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
@@ -266,17 +267,17 @@ void Database::open() {
checkMetaTable();
createTables();
std::cout << "[INFO] Database in operation ";
std::cout << "[INFO] Database in operation";
int accounts = getTableSize("Accounts");
int players = getTableSize("Players");
std::string message = "";
if (accounts > 0) {
message += ": Found " + std::to_string(accounts) + " Account";
message += ": Found " + std::to_string(accounts) + " account";
if (accounts > 1)
message += "s";
}
if (players > 0) {
message += " and " + std::to_string(players) + " Player Character";
message += " and " + std::to_string(players) + " player";
if (players > 1)
message += "s";
}

View File

@@ -208,6 +208,8 @@ void Database::addBlock(int playerId, int blockedPlayerId) {
}
void Database::removeBlock(int playerId, int blockedPlayerId) {
std::lock_guard<std::mutex> lock(dbCrit);
const char* sql = R"(
DELETE FROM Blocks
WHERE PlayerID = ? AND BlockedPlayerID = ?;

View File

@@ -67,6 +67,9 @@ int settings::MONITORINTERVAL = 5000;
// event mode settings
int settings::EVENTMODE = 0;
// race settings
bool settings::IZRACESCORECAPPED = true;
void settings::init() {
INIReader reader("config.ini");
@@ -111,6 +114,7 @@ void settings::init() {
EVENTMODE = reader.GetInteger("shard", "eventmode", EVENTMODE);
DISABLEFIRSTUSEFLAG = reader.GetBoolean("shard", "disablefirstuseflag", DISABLEFIRSTUSEFLAG);
ANTICHEAT = reader.GetBoolean("shard", "anticheat", ANTICHEAT);
IZRACESCORECAPPED = reader.GetBoolean("shard", "izracescorecapped", IZRACESCORECAPPED);
MONITORENABLED = reader.GetBoolean("monitor", "enabled", MONITORENABLED);
MONITORPORT = reader.GetInteger("monitor", "port", MONITORPORT);
MONITORINTERVAL = reader.GetInteger("monitor", "interval", MONITORINTERVAL);

View File

@@ -38,6 +38,7 @@ namespace settings {
extern int MONITORPORT;
extern int MONITORINTERVAL;
extern bool DISABLEFIRSTUSEFLAG;
extern bool IZRACESCORECAPPED;
void init();
}

14838
vendor/JSON.hpp vendored

File diff suppressed because it is too large Load Diff

View File

@@ -22,9 +22,13 @@
#endif
#include <errno.h>
#ifdef _WIN32 || _WIN64
#if defined(_WIN32) || defined(_WIN64)
// 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;
#endif
#define BCRYPT_HASHSIZE 60
#include "bcrypt.h"
@@ -117,7 +121,7 @@ int bcrypt_gensalt(int factor, char salt[BCRYPT_HASHSIZE])
char *aux;
// Note: Windows does not have /dev/urandom sadly.
#ifdef _WIN32 || _WIN64
#if defined(_WIN32) || defined(_WIN64)
HCRYPTPROV p;
ULONG i;

View File

@@ -51,7 +51,7 @@
#endif
/* Just to make sure the prototypes match the actual definitions */
#ifdef _WIN32 || _WIN64
#if defined(_WIN32) || defined(_WIN64)
#include "crypt_blowfish.h"
#else
#include "crypt_blowfish.h"

View File

@@ -41,7 +41,7 @@
#define __SKIP_GNU
#endif
#ifdef _WIN32 | _WIN64
#if defined(_WIN32) || defined(_WIN64)
#include "ow-crypt.h"
#include "crypt_blowfish.h"
@@ -251,7 +251,7 @@ char *__crypt_gensalt_ra(const char *prefix, unsigned long count,
input, size, output, sizeof(output));
if (retval) {
#ifdef _WIN32 | _WIN64
#if defined(_WIN32) || defined(_WIN64)
retval = _strdup(retval);
#else
retval = strdup(retval);