Skip to content

Commit

Permalink
Merge branch 'main' into onRemoveCreature_onCreatureLeave_async
Browse files Browse the repository at this point in the history
  • Loading branch information
mehah committed Dec 6, 2024
2 parents 6f89d1d + b54a712 commit c8f7f30
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 64 deletions.
16 changes: 0 additions & 16 deletions .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ jobs:
with:
install: true

- name: Cache Docker layers
uses: actions/cache@main
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-x86-${{ github.sha }}
restore-keys: |
${{ runner.os }}-x86-
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
Expand Down Expand Up @@ -109,14 +101,6 @@ jobs:
with:
install: true

- name: Cache Docker layers
uses: actions/cache@main
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-arm-${{ github.sha }}
restore-keys: |
${{ runner.os }}-arm-
- name: Build
uses: docker/[email protected]
with:
Expand Down
4 changes: 2 additions & 2 deletions data-otservbr-global/scripts/lib/monster_functions.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function Monster:handleCobraOnSpawn()
if Game.getStorageValue(Global.Storage.CobraFlask) >= os.time() then
monster:setHealth(monster:getMaxHealth() * 0.75)
monster:getPosition():sendMagicEffect(CONST_ME_GREEN_RINGS)
self:setHealth(self:getMaxHealth() * 0.75)
self:getPosition():sendMagicEffect(CONST_ME_GREEN_RINGS)
else
Game.setStorageValue(Global.Storage.CobraFlask, -1)
end
Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile.arm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Stage 1: Download all dependencies
FROM ubuntu:23.04 AS dependencies
FROM ubuntu:24.04 AS dependencies

RUN apt-get update && apt-get install -y --no-install-recommends cmake git \
unzip build-essential ca-certificates curl zip unzip tar \
Expand Down Expand Up @@ -30,7 +30,7 @@ WORKDIR /srv
RUN export VCPKG_ROOT=/opt/vcpkg/ && VCPKG_FORCE_SYSTEM_BINARIES=1 cmake --preset linux-release && cmake --build --preset linux-release

# Stage 3: load data and execute
FROM ubuntu:23.04
FROM ubuntu:24.04

VOLUME [ "/data" ]

Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile.x86
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Stage 1: Download all dependencies
FROM ubuntu:23.04 AS dependencies
FROM ubuntu:24.04 AS dependencies

RUN apt-get update && apt-get install -y --no-install-recommends cmake git \
unzip build-essential ca-certificates curl zip unzip tar \
Expand Down Expand Up @@ -30,7 +30,7 @@ WORKDIR /srv
RUN export VCPKG_ROOT=/opt/vcpkg/ && cmake --preset linux-release && cmake --build --preset linux-release

# Stage 3: load data and execute
FROM ubuntu:23.04
FROM ubuntu:24.04
VOLUME [ "/data" ]

COPY --from=build /srv/build/linux-release/bin/canary /bin/canary
Expand Down
8 changes: 6 additions & 2 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5039,10 +5039,14 @@ ItemsTierCountList Player::getDepotInboxItemsId() const {
ItemsTierCountList itemMap;

const auto &inboxPtr = getInbox();
const auto &container = inboxPtr->getContainer();
const auto &container = inboxPtr ? inboxPtr->getContainer() : nullptr;
if (container) {
for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) {
const auto &item = *it;
if (!item) {
continue;
}

(itemMap[item->getID()])[item->getTier()] += Item::countByType(item, -1);
}
}
Expand Down Expand Up @@ -9073,7 +9077,7 @@ void Player::forgeFuseItems(ForgeAction_t actionType, uint16_t firstItemId, uint

returnValue = g_game().internalAddItem(static_self_cast<Player>(), exaltationContainer, INDEX_WHEREEVER);
if (returnValue != RETURNVALUE_NOERROR) {
g_logger().error("Failed to add exaltation chest to player with name {}", fmt::underlying(ITEM_EXALTATION_CHEST), getName());
g_logger().error("Failed to add exaltation chest to player with name {}", getName());
sendCancelMessage(getReturnMessage(returnValue));
sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR);
return;
Expand Down
64 changes: 37 additions & 27 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@

#include <appearances.pb.h>

std::vector<std::shared_ptr<Creature>> checkCreatureLists[EVENT_CREATURECOUNT];
std::vector<std::weak_ptr<Creature>> checkCreatureLists[EVENT_CREATURECOUNT];

namespace InternalGame {
void sendBlockEffect(BlockType_t blockType, CombatType_t combatType, const Position &targetPos, const std::shared_ptr<Creature> &source) {
Expand Down Expand Up @@ -6461,16 +6461,15 @@ void Game::addCreatureCheck(const std::shared_ptr<Creature> &creature) {

creature->creatureCheck.store(true);

if (creature->inCheckCreaturesVector.load()) {
if (creature->inCheckCreaturesVector.exchange(true)) {
// already in a vector
return;
}

creature->inCheckCreaturesVector.store(true);

creature->safeCall([this, creature] {
checkCreatureLists[uniform_random(0, EVENT_CREATURECOUNT - 1)].emplace_back(creature);
});
g_dispatcher().addEvent([this, index = uniform_random(0, EVENT_CREATURECOUNT - 1), creature] {
checkCreatureLists[index].emplace_back(creature);
},
"Game::addCreatureCheck");
}

void Game::removeCreatureCheck(const std::shared_ptr<Creature> &creature) {
Expand All @@ -6484,15 +6483,18 @@ void Game::checkCreatures() {
metrics::method_latency measure(__METRICS_METHOD_NAME__);
static size_t index = 0;

std::erase_if(checkCreatureLists[index], [this](const std::shared_ptr<Creature> creature) {
if (creature->creatureCheck && creature->isAlive()) {
creature->onThink(EVENT_CREATURE_THINK_INTERVAL);
creature->onAttacking(EVENT_CREATURE_THINK_INTERVAL);
creature->executeConditions(EVENT_CREATURE_THINK_INTERVAL);
return false;
std::erase_if(checkCreatureLists[index], [this](const std::weak_ptr<Creature> &weak) {
if (const auto creature = weak.lock()) {
if (creature->creatureCheck && creature->isAlive()) {
creature->onThink(EVENT_CREATURE_THINK_INTERVAL);
creature->onAttacking(EVENT_CREATURE_THINK_INTERVAL);
creature->executeConditions(EVENT_CREATURE_THINK_INTERVAL);
return false;
}

creature->inCheckCreaturesVector = false;
}

creature->inCheckCreaturesVector = false;
return true;
});

Expand Down Expand Up @@ -9025,7 +9027,7 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite
return;
}

std::shared_ptr<DepotLocker> depotLocker = player->getDepotLocker(player->getLastDepotId());
const std::shared_ptr<DepotLocker> &depotLocker = player->getDepotLocker(player->getLastDepotId());
if (depotLocker == nullptr) {
offerStatus << "Depot locker is nullptr for player " << player->getName();
return;
Expand Down Expand Up @@ -9108,6 +9110,7 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
return;
}

const auto &playerInbox = player->getInbox();
if (offer.type == MARKETACTION_BUY) {
player->setBankBalance(player->getBankBalance() + offer.price * offer.amount);
g_metrics().addCounter("balance_decrease", offer.price * offer.amount, { { "player", player->getName() }, { "context", "market_purchase" } });
Expand All @@ -9124,10 +9127,11 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
player->getAccount()->addCoins(CoinType::Transferable, offer.amount, "");
} else if (it.stackable) {
uint16_t tmpAmount = offer.amount;

while (tmpAmount > 0) {
int32_t stackCount = std::min<int32_t>(it.stackSize, tmpAmount);
const auto &item = Item::CreateItem(it.id, stackCount);
if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
if (internalAddItem(playerInbox, item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
break;
}

Expand All @@ -9147,7 +9151,7 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16

for (uint16_t i = 0; i < offer.amount; ++i) {
const auto &item = Item::CreateItem(it.id, subType);
if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
if (internalAddItem(playerInbox, item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
break;
}

Expand Down Expand Up @@ -9205,35 +9209,41 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
return;
}

const auto &playerInbox = player->getInbox();

uint64_t totalPrice = offer.price * amount;

// The player has an offer to by something and someone is going to sell to item type
// so the market action is 'buy' as who created the offer is buying.
if (offer.type == MARKETACTION_BUY) {
std::shared_ptr<DepotLocker> depotLocker = player->getDepotLocker(player->getLastDepotId());
const std::shared_ptr<DepotLocker> &depotLocker = player->getDepotLocker(player->getLastDepotId());
if (depotLocker == nullptr) {
offerStatus << "Depot locker is nullptr";
return;
}

std::shared_ptr<Player> buyerPlayer = getPlayerByGUID(offer.playerId, true);
const std::shared_ptr<Player> &buyerPlayer = getPlayerByGUID(offer.playerId, true);
if (!buyerPlayer) {
offerStatus << "Failed to load buyer player " << player->getName();
return;
}

if (!buyerPlayer->getAccount()) {
const auto &buyerPlayerAccount = buyerPlayer->getAccount();
if (!buyerPlayerAccount) {
player->sendTextMessage(MESSAGE_MARKET, "Cannot accept offer.");
return;
}

if (player == buyerPlayer || player->getAccount() == buyerPlayer->getAccount()) {
const auto &playerAccount = player->getAccount();
if (player == buyerPlayer || playerAccount == buyerPlayerAccount) {
player->sendTextMessage(MESSAGE_MARKET, "You cannot accept your own offer.");
return;
}

const auto &buyerPlayerInbox = buyerPlayer->getInbox();

if (it.id == ITEM_STORE_COIN) {
auto [transferableCoins, error] = player->getAccount()->getCoins(CoinType::Transferable);
auto [transferableCoins, error] = playerAccount->getCoins(CoinType::Transferable);

if (error != AccountErrors_t::Ok) {
offerStatus << "Failed to load transferable coins for player " << player->getName();
Expand All @@ -9245,7 +9255,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
return;
}

player->getAccount()->removeCoins(
playerAccount->removeCoins(
CoinType::Transferable,
amount,
"Sold on Market"
Expand Down Expand Up @@ -9280,7 +9290,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
while (tmpAmount > 0) {
uint16_t stackCount = std::min<uint16_t>(it.stackSize, tmpAmount);
const auto &item = Item::CreateItem(it.id, stackCount);
if (internalAddItem(buyerPlayer->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
if (internalAddItem(buyerPlayerInbox, item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
offerStatus << "Failed to add player inbox stackable item for buy offer for player " << player->getName();

break;
Expand All @@ -9302,7 +9312,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16

for (uint16_t i = 0; i < amount; ++i) {
const auto &item = Item::CreateItem(it.id, subType);
if (internalAddItem(buyerPlayer->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
if (internalAddItem(buyerPlayerInbox, item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
offerStatus << "Failed to add player inbox item for buy offer for player " << player->getName();

break;
Expand Down Expand Up @@ -9353,7 +9363,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
const auto &item = Item::CreateItem(it.id, stackCount);
if (
// Init-statement
auto ret = internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT);
auto ret = internalAddItem(playerInbox, item, INDEX_WHEREEVER, FLAG_NOLIMIT);
// Condition
ret != RETURNVALUE_NOERROR
) {
Expand Down Expand Up @@ -9381,7 +9391,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
const auto &item = Item::CreateItem(it.id, subType);
if (
// Init-statement
auto ret = internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT);
auto ret = internalAddItem(playerInbox, item, INDEX_WHEREEVER, FLAG_NOLIMIT);
// Condition
ret != RETURNVALUE_NOERROR
) {
Expand Down
1 change: 1 addition & 0 deletions src/game/scheduling/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class Task {
"Game::createInfluencedMonsters",
"Game::updateCreatureWalk",
"Game::updateForgeableMonsters",
"Game::addCreatureCheck",
"GlobalEvents::think",
"LuaEnvironment::executeTimerEvent",
"Modules::executeOnRecvbyte",
Expand Down
12 changes: 9 additions & 3 deletions src/io/functions/iologindata_load_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,16 +679,22 @@ void IOLoginDataLoad::loadPlayerInboxItems(const std::shared_ptr<Player> &player
ItemsMap inboxItems;
loadItems(inboxItems, result, player);

for (auto it = inboxItems.rbegin(), end = inboxItems.rend(); it != end; ++it) {
const std::pair<std::shared_ptr<Item>, int32_t> &pair = it->second;
const auto &playerInbox = player->getInbox();
if (!playerInbox) {
g_logger().warn("[{}] - Player inbox nullptr", __FUNCTION__);
return;
}

for (const auto &it : std::ranges::reverse_view(inboxItems)) {
const std::pair<std::shared_ptr<Item>, int32_t> &pair = it.second;
const auto &item = pair.first;
if (!item) {
continue;
}

int32_t pid = pair.second;
if (pid >= 0 && pid < 100) {
player->getInbox()->internalAddThing(item);
playerInbox->internalAddThing(item);
item->startDecaying();
} else {
auto inboxIt = inboxItems.find(pid);
Expand Down
6 changes: 4 additions & 2 deletions src/io/iomarket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,14 @@ void IOMarket::processExpiredOffers(const DBResult_ptr &result, bool) {
continue;
}

const auto &playerInbox = player->getInbox();

if (itemType.stackable) {
uint16_t tmpAmount = amount;
while (tmpAmount > 0) {
uint16_t stackCount = std::min<uint16_t>(100, tmpAmount);
const auto &item = Item::CreateItem(itemType.id, stackCount);
if (g_game().internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
if (g_game().internalAddItem(playerInbox, item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
g_logger().error("[{}] Ocurred an error to add item with id {} to player {}", __FUNCTION__, itemType.id, player->getName());

break;
Expand All @@ -202,7 +204,7 @@ void IOMarket::processExpiredOffers(const DBResult_ptr &result, bool) {

for (uint16_t i = 0; i < amount; ++i) {
const auto &item = Item::CreateItem(itemType.id, subType);
if (g_game().internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
if (g_game().internalAddItem(playerInbox, item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) {
break;
}

Expand Down
19 changes: 14 additions & 5 deletions src/items/containers/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ std::shared_ptr<Container> Container::createBrowseField(const std::shared_ptr<Ti

Container::~Container() {
if (getID() == ITEM_BROWSEFIELD) {
auto parent = getParent();
const auto &parent = getParent();
if (parent) {
auto tile = parent->getTile();
const auto &tile = parent->getTile();
if (tile) {
auto browseField = g_game().browseFields.find(tile);
if (browseField != g_game().browseFields.end()) {
Expand Down Expand Up @@ -385,7 +385,12 @@ uint32_t Container::getContainerHoldingCount() {

bool Container::isHoldingItem(const std::shared_ptr<Item> &item) {
for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) {
if (*it == item) {
const auto &compareItem = *it;
if (!compareItem || !item) {
continue;
}

if (compareItem == item) {
return true;
}
}
Expand All @@ -395,6 +400,10 @@ bool Container::isHoldingItem(const std::shared_ptr<Item> &item) {
bool Container::isHoldingItemWithId(const uint16_t id) {
for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) {
const auto &item = *it;
if (!item) {
continue;
}

if (item && item->getID() == id) {
return true;
}
Expand Down Expand Up @@ -1024,9 +1033,9 @@ void ContainerIterator::advance() {
return;
}

auto currentItem = container->itemlist[top.index];
const auto &currentItem = container->itemlist[top.index];
if (currentItem) {
auto subContainer = currentItem->getContainer();
const auto &subContainer = currentItem->getContainer();
if (subContainer && !subContainer->itemlist.empty()) {
size_t newDepth = top.depth + 1;
if (newDepth <= maxTraversalDepth) {
Expand Down
Loading

0 comments on commit c8f7f30

Please sign in to comment.