Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mattyx14 committed Nov 1, 2023
1 parent 4c2003e commit 4c7786e
Show file tree
Hide file tree
Showing 111 changed files with 2,548 additions and 1,146 deletions.
16 changes: 9 additions & 7 deletions .github/workflows/build-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ env:
MAKEFLAGS: '-j 2'

jobs:
cancel-runs:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}

job:
if: ${{ github.event_name == 'push' || !github.event.pull_request.draft }}
name: ${{ matrix.os }}-${{ matrix.buildtype }}
Expand All @@ -35,13 +44,6 @@ jobs:
triplet: x64-linux

steps:
- name: Cancel Previous Runs
if: github.ref != 'refs/heads/main'
uses: fkirc/skip-duplicate-actions@master
with:
concurrent_skipping: 'same_content'
cancel_others: true

- name: Checkout repository
uses: actions/checkout@main

Expand Down
16 changes: 9 additions & 7 deletions .github/workflows/build-windows-cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ env:
CMAKE_BUILD_PARALLEL_LEVEL: 2
MAKEFLAGS: '-j 2'
jobs:
cancel-runs:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}

job:
if: ${{ github.event_name == 'push' || !github.event.pull_request.draft }}
name: ${{ matrix.os }}-${{ matrix.buildtype }}
Expand All @@ -29,13 +38,6 @@ jobs:
packages: >
sccache
steps:
- name: Cancel Previous Runs
if: github.ref != 'refs/heads/main'
uses: fkirc/skip-duplicate-actions@master
with:
concurrent_skipping: 'same_content'
cancel_others: true

- name: Checkout repository
uses: actions/checkout@main

Expand Down
4 changes: 2 additions & 2 deletions schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS `server_config` (
CONSTRAINT `server_config_pk` PRIMARY KEY (`config`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '38'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');
INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '41'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');

-- Table structure `accounts`
CREATE TABLE IF NOT EXISTS `accounts` (
Expand Down Expand Up @@ -438,7 +438,7 @@ DELIMITER ;
CREATE TABLE IF NOT EXISTS `house_lists` (
`house_id` int NOT NULL,
`listid` int NOT NULL,
`version` int NOT NULL DEFAULT '0',
`version` bigint NOT NULL DEFAULT '0',
`list` text NOT NULL,
PRIMARY KEY (`house_id`, `listid`),
KEY `house_id_index` (`house_id`),
Expand Down
2 changes: 1 addition & 1 deletion src/account/account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace account {
return ERROR_NO;
}

if (!m_descriptor.empty() && accountRepository.loadByEmail(m_descriptor, m_account)) {
if (!m_descriptor.empty() && accountRepository.loadByEmailOrName(getProtocolCompat(), m_descriptor, m_account)) {
m_accLoaded = true;
return ERROR_NO;
}
Expand Down
2 changes: 1 addition & 1 deletion src/account/account_repository.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace account {
virtual ~AccountRepository() = default;

virtual bool loadByID(const uint32_t &id, AccountInfo &acc) = 0;
virtual bool loadByEmail(const std::string &email, AccountInfo &acc) = 0;
virtual bool loadByEmailOrName(bool oldProtocol, const std::string &emailOrName, AccountInfo &acc) = 0;
virtual bool loadBySession(const std::string &email, AccountInfo &acc) = 0;
virtual bool save(const AccountInfo &accInfo) = 0;

Expand Down
7 changes: 4 additions & 3 deletions src/account/account_repository_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ namespace account {
return load(query, acc);
};

bool AccountRepositoryDB::loadByEmail(const std::string &email, AccountInfo &acc) {
auto query = fmt::format("SELECT `id`, `type`, `premdays`, `lastday`, `creation`, `premdays_purchased`, 0 AS `expires` FROM `accounts` WHERE `email` = {}", db.escapeString(email));
bool AccountRepositoryDB::loadByEmailOrName(bool oldProtocol, const std::string &emailOrName, AccountInfo &acc) {
auto identifier = oldProtocol ? "name" : "email";
auto query = fmt::format("SELECT `id`, `type`, `premdays`, `lastday`, `creation`, `premdays_purchased`, 0 AS `expires` FROM `accounts` WHERE `{}` = {}", identifier, db.escapeString(emailOrName));
return load(query, acc);
};

Expand Down Expand Up @@ -163,7 +164,7 @@ namespace account {
acc.premiumLastDay = result->getNumber<time_t>("lastday");
acc.sessionExpires = result->getNumber<time_t>("expires");
acc.premiumDaysPurchased = result->getNumber<uint32_t>("premdays_purchased");
acc.creationTime = result->getNumber<time_t>("creation");
acc.creationTime = result->getNumber<uint32_t>("creation");

setupLoyaltyInfo(acc);

Expand Down
2 changes: 1 addition & 1 deletion src/account/account_repository_db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace account {
db(db), logger(logger) { }

bool loadByID(const uint32_t &id, AccountInfo &acc) override;
bool loadByEmail(const std::string &email, AccountInfo &acc) override;
bool loadByEmailOrName(bool oldProtocol, const std::string &emailOrName, AccountInfo &acc) override;
bool loadBySession(const std::string &esseionKey, AccountInfo &acc) override;
bool save(const AccountInfo &accInfo) override;

Expand Down
18 changes: 12 additions & 6 deletions src/canary_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "creatures/players/storages/storages.hpp"
#include "database/databasemanager.hpp"
#include "game/game.hpp"
#include "game/zones/zone.hpp"
#include "game/scheduling/dispatcher.hpp"
#include "game/scheduling/events_scheduler.hpp"
#include "io/iomarket.hpp"
Expand All @@ -25,6 +26,7 @@
#include "lua/scripts/lua_environment.hpp"
#include "lua/scripts/scripts.hpp"
#include "server/network/protocol/protocollogin.hpp"
#include "server/network/protocol/protocolstatus.hpp"
#include "server/network/webhook/webhook.hpp"
#include "io/ioprey.hpp"
#include "io/io_bosstiary.hpp"
Expand All @@ -46,13 +48,15 @@ CanaryServer::CanaryServer(
std::set_new_handler(badAllocationHandler);
srand(static_cast<unsigned int>(OTSYS_TIME()));

g_dispatcher().init();

#ifdef _WIN32
SetConsoleTitleA(STATUS_SERVER_NAME);
SetConsoleTitleA(ProtocolStatus::SERVER_NAME.c_str());
#endif
}

int CanaryServer::run() {
g_dispatcher().addTask(
g_dispatcher().addEvent(
[this] {
try {
loadConfigLua();
Expand Down Expand Up @@ -80,7 +84,7 @@ int CanaryServer::run() {
if (getuid() == 0 || geteuid() == 0) {
logger.warn("{} has been executed as root user, "
"please consider running it as a normal user",
STATUS_SERVER_NAME);
ProtocolStatus::SERVER_NAME);
}
#endif

Expand Down Expand Up @@ -151,6 +155,7 @@ void CanaryServer::loadMaps() const {
if (g_configManager().getBoolean(TOGGLE_MAP_CUSTOM)) {
g_game().loadCustomMaps(g_configManager().getString(DATA_DIRECTORY) + "/world/custom/");
}
Zone::refreshAll();
} catch (const std::exception &err) {
throw FailedToInitializeCanary(err.what());
}
Expand All @@ -177,12 +182,12 @@ void CanaryServer::setupHousesRent() {

void CanaryServer::logInfos() {
#if defined(GIT_RETRIEVED_STATE) && GIT_RETRIEVED_STATE
logger.debug("{} - Version [{}] dated [{}]", STATUS_SERVER_NAME, STATUS_SERVER_VERSION, GIT_COMMIT_DATE_ISO8601);
logger.debug("{} - Version [{}] dated [{}]", ProtocolStatus::SERVER_NAME, SERVER_RELEASE_VERSION, GIT_COMMIT_DATE_ISO8601);
#if GIT_IS_DIRTY
logger.debug("DIRTY - NOT OFFICIAL RELEASE");
#endif
#else
logger.info("The {} - Version {}", STATUS_SERVER_NAME, STATUS_SERVER_VERSION);
logger.info("{} - Version {}", ProtocolStatus::SERVER_NAME, SERVER_RELEASE_VERSION);
#endif

logger.debug("Compiled with {}, on {} {}, for platform {}\n", getCompiler(), __DATE__, __TIME__, getPlatform());
Expand All @@ -191,7 +196,7 @@ void CanaryServer::logInfos() {
logger.debug("Linked with {} for Lua support", LUAJIT_VERSION);
#endif

logger.info("A server developed by: {}", STATUS_SERVER_DEVELOPERS);
logger.info("A server developed by: {}", ProtocolStatus::SERVER_DEVELOPERS);
logger.info("Visit our website for updates, support, and resources:\n"
"https://docs.opentibiabr.com/home/welcome/ \n"
"https://github.com/mattyx14/otxserver/\n");
Expand Down Expand Up @@ -366,4 +371,5 @@ void CanaryServer::modulesLoadHelper(bool loaded, std::string moduleName) {

void CanaryServer::shutdown() {
inject<ThreadPool>().shutdown();
g_dispatcher().shutdown();
}
7 changes: 3 additions & 4 deletions src/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@

#pragma once

static constexpr auto STATUS_SERVER_NAME = "OTX Server";
static constexpr auto STATUS_SERVER_VERSION = "6.2";
static constexpr auto STATUS_SERVER_DEVELOPERS = "Canary Base - OpenTibiaBR Organization and data editor: Mattyx14";

static constexpr auto AUTHENTICATOR_DIGITS = 6U;
static constexpr auto AUTHENTICATOR_PERIOD = 30U;

// SERVER_MAJOR_VERSION is the actual full version of the server, including minor and patch numbers.
// This is intended for internal use to identify the exact state of the server (release) software.
static constexpr auto SERVER_RELEASE_VERSION = "6.2.0";
static constexpr auto CLIENT_VERSION = 1321;

#define CLIENT_VERSION_UPPER (CLIENT_VERSION / 100)
Expand Down
139 changes: 65 additions & 74 deletions src/creatures/combat/combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1139,41 +1139,7 @@ void Combat::doCombatHealth(std::shared_ptr<Creature> caster, std::shared_ptr<Cr
}
}

if (!damage.extension && caster && caster->getPlayer()) {
// Critical damage
uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance;
// Charm low blow rune)
if (target && target->getMonster() && damage.primary.type != COMBAT_HEALING) {
uint16_t playerCharmRaceid = caster->getPlayer()->parseRacebyCharm(CHARM_LOW, false, 0);
if (playerCharmRaceid != 0) {
const auto mType = g_monsters().getMonsterType(target->getName());
if (mType && playerCharmRaceid == mType->info.raceid) {
const auto charm = g_iobestiary().getBestiaryCharm(CHARM_LOW);
if (charm) {
chance += charm->percent;
g_game().sendDoubleSoundEffect(target->getPosition(), charm->soundCastEffect, charm->soundImpactEffect, caster);
}
}
}
}
if (chance != 0 && uniform_random(1, 100) <= chance) {
damage.critical = true;
damage.primary.value += (damage.primary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
}

// Fatal hit (onslaught)
if (auto playerWeapon = caster->getPlayer()->getInventoryItem(CONST_SLOT_LEFT);
playerWeapon != nullptr && playerWeapon->getTier()) {
double_t fatalChance = playerWeapon->getFatalChance();
double_t randomChance = uniform_random(0, 10000) / 100;
if (damage.primary.type != COMBAT_HEALING && fatalChance > 0 && randomChance < fatalChance) {
damage.fatal = true;
damage.primary.value += static_cast<int32_t>(std::round(damage.primary.value * 0.6));
damage.secondary.value += static_cast<int32_t>(std::round(damage.secondary.value * 0.6));
}
}
}
applyExtensions(caster, target, damage, params);

if (canCombat) {
if (target && caster && params.distanceEffect != CONST_ANI_NONE) {
Expand All @@ -1194,27 +1160,7 @@ void Combat::doCombatHealth(std::shared_ptr<Creature> caster, std::shared_ptr<Cr
}

void Combat::doCombatHealth(std::shared_ptr<Creature> caster, const Position &position, const std::unique_ptr<AreaCombat> &area, CombatDamage &damage, const CombatParams &params) {
if (caster && caster->getPlayer()) {
// Critical damage
uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance;
if (damage.primary.type != COMBAT_HEALING && chance != 0 && uniform_random(1, 100) <= chance) {
damage.critical = true;
damage.primary.value += (damage.primary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
}

// Fatal hit (onslaught)
if (auto playerWeapon = caster->getPlayer()->getInventoryItem(CONST_SLOT_LEFT);
playerWeapon != nullptr && playerWeapon->getTier() > 0) {
double_t fatalChance = playerWeapon->getFatalChance();
double_t randomChance = uniform_random(0, 10000) / 100;
if (damage.primary.type != COMBAT_HEALING && fatalChance > 0 && randomChance < fatalChance) {
damage.fatal = true;
damage.primary.value += static_cast<int32_t>(std::round(damage.primary.value * 0.6));
damage.secondary.value += static_cast<int32_t>(std::round(damage.secondary.value * 0.6));
}
}
}
applyExtensions(caster, nullptr, damage, params);
const auto origin = caster ? caster->getPosition() : Position();
CombatFunc(caster, origin, position, area, params, CombatHealthFunc, &damage);
}
Expand All @@ -1231,15 +1177,7 @@ void Combat::doCombatMana(std::shared_ptr<Creature> caster, std::shared_ptr<Crea
g_game().addMagicEffect(target->getPosition(), params.impactEffect);
}

if (caster && caster->getPlayer()) {
// Critical damage
uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance;
if (chance != 0 && uniform_random(1, 100) <= chance) {
damage.critical = true;
damage.primary.value += (damage.primary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
}
}
applyExtensions(caster, target, damage, params);

if (canCombat) {
if (caster && target && params.distanceEffect != CONST_ANI_NONE) {
Expand All @@ -1260,15 +1198,7 @@ void Combat::doCombatMana(std::shared_ptr<Creature> caster, std::shared_ptr<Crea
}

void Combat::doCombatMana(std::shared_ptr<Creature> caster, const Position &position, const std::unique_ptr<AreaCombat> &area, CombatDamage &damage, const CombatParams &params) {
if (caster && caster->getPlayer()) {
// Critical damage
uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance;
if (chance != 0 && uniform_random(1, 100) <= chance) {
damage.critical = true;
damage.primary.value += (damage.primary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
}
}
applyExtensions(caster, nullptr, damage, params);
const auto origin = caster ? caster->getPosition() : Position();
CombatFunc(caster, origin, position, area, params, CombatManaFunc, &damage);
}
Expand Down Expand Up @@ -2080,3 +2010,64 @@ void MagicField::onStepInField(const std::shared_ptr<Creature> &creature) {
creature->addCondition(conditionCopy);
}
}

void Combat::applyExtensions(std::shared_ptr<Creature> caster, std::shared_ptr<Creature> target, CombatDamage &damage, const CombatParams &params) {
if (damage.extension || !caster || damage.primary.type == COMBAT_HEALING) {
return;
}

g_logger().trace("[Combat::applyExtensions] - Applying extensions for {} on {}. Initial damage: {}", caster->getName(), target ? target->getName() : "null", damage.primary.value);

// Critical hit
uint16_t chance = 0;
int32_t multiplier = 50;
auto player = caster->getPlayer();
auto monster = caster->getMonster();
if (player) {
chance = player->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE);
multiplier = player->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE);

if (target) {
uint16_t playerCharmRaceid = player->parseRacebyCharm(CHARM_LOW, false, 0);
if (playerCharmRaceid != 0) {
const auto mType = g_monsters().getMonsterType(target->getName());
if (mType && playerCharmRaceid == mType->info.raceid) {
const auto charm = g_iobestiary().getBestiaryCharm(CHARM_LOW);
if (charm) {
chance += charm->percent;
g_game().sendDoubleSoundEffect(target->getPosition(), charm->soundCastEffect, charm->soundImpactEffect, caster);
}
}
}
}
} else if (monster) {
chance = monster->critChance();
}

multiplier += damage.criticalDamage;
multiplier = 1 + multiplier / 100;
chance += (uint16_t)damage.criticalChance;

if (chance != 0 && uniform_random(1, 100) <= chance) {
damage.critical = true;
damage.primary.value *= multiplier;
damage.secondary.value *= multiplier;
}

if (player) {
// Fatal hit (onslaught)
if (auto playerWeapon = player->getInventoryItem(CONST_SLOT_LEFT);
playerWeapon != nullptr && playerWeapon->getTier() > 0) {
double_t fatalChance = playerWeapon->getFatalChance();
double_t randomChance = uniform_random(0, 10000) / 100;
if (fatalChance > 0 && randomChance < fatalChance) {
damage.fatal = true;
damage.primary.value += static_cast<int32_t>(std::round(damage.primary.value * 0.6));
damage.secondary.value += static_cast<int32_t>(std::round(damage.secondary.value * 0.6));
}
}
} else if (monster) {
damage.primary.value *= monster->getAttackMultiplier();
damage.secondary.value *= monster->getAttackMultiplier();
}
}
Loading

0 comments on commit 4c7786e

Please sign in to comment.