Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
MillhioreBT committed Apr 16, 2024
1 parent 9a70306 commit a8a38e5
Show file tree
Hide file tree
Showing 23 changed files with 374 additions and 50 deletions.
1 change: 1 addition & 0 deletions src/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ void Connection::parsePacket(const boost::system::error_code& error)
if (!receivedFirst) {
// First message received
receivedFirst = true;
lastIp = getIP();

if (!protocol) {
// Game protocol has already been created at this point
Expand Down
2 changes: 2 additions & 0 deletions src/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class Connection : public std::enable_shared_from_this<Connection>
void send(const OutputMessage_ptr& msg);

uint32_t getIP();
uint32_t getLastIp() const { return lastIp; }

private:
void parseHeader(const boost::system::error_code& error);
Expand Down Expand Up @@ -106,6 +107,7 @@ class Connection : public std::enable_shared_from_this<Connection>

time_t timeConnected;
uint32_t packetsSent = 0;
uint32_t lastIp = 0;

bool closed = false;
bool receivedFirst = false;
Expand Down
4 changes: 2 additions & 2 deletions src/creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ class Creature : virtual public Thing
// for lua module
CreatureEventList getCreatureEvents(CreatureEventType_t type) const;

void setHealth(int32_t newHealth) { health = std::min<int32_t>(newHealth, healthMax); }
void setMaxHealth(int32_t newMaxHealth) { healthMax = newMaxHealth; }
void setHealth(int32_t newHealth) { health = std::max<int32_t>(0, std::min<int32_t>(newHealth, healthMax)); }
void setMaxHealth(int32_t newMaxHealth) { healthMax = std::max<int32_t>(0, newMaxHealth); }

void setDefaultOutfit(Outfit_t outfit) { defaultOutfit = outfit; }

Expand Down
14 changes: 14 additions & 0 deletions src/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,12 @@ enum ConditionParam_t
CONDITION_PARAM_SPECIALSKILL_MANALEECHAMOUNT = 53,
CONDITION_PARAM_AGGRESSIVE = 54,
CONDITION_PARAM_DRUNKENNESS = 55,
CONDITION_PARAM_EXPERIENCERATE_BASE = 56,
CONDITION_PARAM_EXPERIENCERATE_LOW_LEVEL = 57,
CONDITION_PARAM_EXPERIENCERATE_BONUS = 58,
CONDITION_PARAM_EXPERIENCERATE_STAMINA = 59,
CONDITION_PARAM_HEALTHGAINPERCENT = 60,
CONDITION_PARAM_MANAGAINPERCENT = 61,
};

enum BlockType_t : uint8_t
Expand Down Expand Up @@ -498,6 +504,14 @@ enum MapMark_t
MAPMARK_GREENSOUTH = 19,
};

enum class ExperienceRateType : uint8_t
{
BASE = 1,
LOW_LEVEL = 2,
BONUS = 3,
STAMINA = 4,
};

struct Outfit_t
{
uint16_t lookType = 0;
Expand Down
63 changes: 63 additions & 0 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ void Game::setGameState(GameState_t newState)

loadMotdNum();
loadPlayersRecord();
loadGameStorageValues();
loadAccountStorageValues();

g_globalEvents->startup();
Expand Down Expand Up @@ -138,6 +139,10 @@ void Game::saveGameState()

std::cout << "Saving server..." << std::endl;

if (!saveGameStorageValues()) {
std::cout << "[Error - Game::saveGameState] Failed to save game storage values." << std::endl;
}

if (!saveAccountStorageValues()) {
std::cout << "[Error - Game::saveGameState] Failed to save account-level storage values." << std::endl;
}
Expand Down Expand Up @@ -5335,3 +5340,61 @@ bool Game::reload(ReloadTypes_t reloadType)
}
return true;
}

void Game::loadGameStorageValues()
{
Database& db = Database::getInstance();

DBResult_ptr result;
if ((result = db.storeQuery("SELECT `key`, `value` FROM `game_storage`"))) {
do {
g_game.setStorageValue(result->getNumber<uint32_t>("key"), result->getNumber<int32_t>("value"));
} while (result->next());
}
}

bool Game::saveGameStorageValues() const
{
DBTransaction transaction;
Database& db = Database::getInstance();

if (!transaction.begin()) {
return false;
}

if (!db.executeQuery("DELETE FROM `game_storage`")) {
return false;
}

for (const auto& [key, value] : g_game.storageMap) {
DBInsert gameStorageQuery("INSERT INTO `game_storage` (`key`, `value`) VALUES");
if (!gameStorageQuery.addRow(fmt::format("{:d}, {:d}", key, value))) {
return false;
}

if (!gameStorageQuery.execute()) {
return false;
}
}

return transaction.commit();
}

void Game::setStorageValue(uint32_t key, std::optional<int64_t> value)
{
auto oldValue = getStorageValue(key);
if (value) {
storageMap.insert_or_assign(key, value.value());
} else {
storageMap.erase(key);
}
}

std::optional<int64_t> Game::getStorageValue(uint32_t key) const
{
auto it = storageMap.find(key);
if (it == storageMap.end()) {
return std::nullopt;
}
return std::make_optional(it->second);
}
9 changes: 9 additions & 0 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,16 @@ class Game
void removeTileToClean(Tile* tile) { tilesToClean.erase(tile); }
void clearTilesToClean() { tilesToClean.clear(); }

void loadGameStorageValues();
bool saveGameStorageValues() const;

virtual void setStorageValue(uint32_t key, std::optional<int64_t> value);
virtual std::optional<int64_t> getStorageValue(uint32_t key) const;
decltype(auto) getStorageMap() const { return storageMap; }

private:
std::map<uint32_t, int64_t> storageMap;

bool playerSaySpell(Player* player, SpeakClasses type, std::string_view text);
void playerWhisper(Player* player, std::string_view text);
bool playerYell(Player* player, std::string_view text);
Expand Down
4 changes: 4 additions & 0 deletions src/housetile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ void HouseTile::updateHouse(Item* item)
ReturnValue HouseTile::queryAdd(int32_t index, const Thing& thing, uint32_t count, uint32_t flags,
Creature* actor /* = nullptr*/) const
{
if (hasBitSet(FLAG_NOLIMIT, flags)) {
return RETURNVALUE_NOERROR;
}

if (const Creature* creature = thing.getCreature()) {
if (const Player* player = creature->getPlayer()) {
if (!house->isInvited(player)) {
Expand Down
24 changes: 15 additions & 9 deletions src/luacreature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,20 +515,27 @@ int luaCreatureGetHealth(lua_State* L)

int luaCreatureSetHealth(lua_State* L)
{
// creature:setHealth(health)
// creature:setHealth(health[, actor = nil])
Creature* creature = getUserdata<Creature>(L, 1);
if (!creature) {
lua_pushnil(L);
return 1;
}

creature->setHealth(getInteger<uint32_t>(L, 2));
g_game.addCreatureHealth(creature);
auto health = getInteger<int32_t>(L, 2);
if (health > 0) {
creature->setHealth(health);
g_game.addCreatureHealth(creature);
} else {
creature->drainHealth(getCreature(L, 3), creature->getHealth());
}

Player* player = creature->getPlayer();
if (player) {
player->sendStats();
if (!creature->isDead()) {
if (dynamic_cast<Player*>(creature) != nullptr) {
static_cast<Player*>(creature)->sendStats();
}
}

pushBoolean(L, true);
return 1;
}
Expand Down Expand Up @@ -785,9 +792,8 @@ int luaCreatureRemove(lua_State* L)
return 1;
}

Player* player = creature->getPlayer();
if (player) {
player->kickPlayer(true);
if (dynamic_cast<Player*>(creature) != nullptr) {
static_cast<Player*>(creature)->kickPlayer(true);
} else {
g_game.removeCreature(creature);
}
Expand Down
61 changes: 61 additions & 0 deletions src/luagame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,62 @@ int luaGameGetWaypoints(lua_State* L)
}
return 1;
}

int luaGameGetThingFromClientPos(lua_State* L)
{
// Game.getThingFromClientPos(player, position, stackPos)
const auto player = getPlayer(L, 1);
const Position& position = getPosition(L, 2);
const auto stackPos = getInteger<uint8_t>(L, 3);
auto thing = g_game.internalGetThing(player, position, stackPos, 0, STACKPOS_LOOK);
pushThing(L, thing);
return 1;
}

int luaGameGetGameStorageValue(lua_State* L)
{
// Game.getStorageValue(key)
uint32_t key = getInteger<uint32_t>(L, 1);

const auto& value = g_game.getStorageValue(key);
if (value) {
lua_pushinteger(L, value.value());
} else if (isInteger(L, 3)) {
lua_pushinteger(L, getInteger<int64_t>(L, 3));
} else {
lua_pushnil(L);
}
return 1;
}

int luaGameSetGameStorageValue(lua_State* L)
{
// Game.setGameStorageValue(key, value)
if (!isInteger(L, 1)) {
reportErrorFunc(L, "Invalid storage key.");
lua_pushnil(L);
return 1;
}

uint32_t key = getInteger<uint32_t>(L, 1);
if (isInteger(L, 2)) {
int64_t value = getInteger<int64_t>(L, 2);
g_game.setStorageValue(key, value);
} else {
g_game.setStorageValue(key, std::nullopt);
}

pushBoolean(L, true);
return 1;
}

int luaGameSaveGameStorageValues(lua_State* L)
{
// Game.saveStorageValues()
pushBoolean(L, g_game.saveGameStorageValues());

return 1;
}
} // namespace

void LuaScriptInterface::registerGame()
Expand Down Expand Up @@ -705,4 +761,9 @@ void LuaScriptInterface::registerGame()
registerMethod("Game", "saveAccountStorageValues", luaGameSaveAccountStorageValues);

registerMethod("Game", "getWaypoints", luaGameGetWaypoints);
registerMethod("Game", "getThingFromClientPos", luaGameGetThingFromClientPos);

registerMethod("Game", "getStorageValue", luaGameGetGameStorageValue);
registerMethod("Game", "setStorageValue", luaGameSetGameStorageValue);
registerMethod("Game", "saveStorageValues", luaGameSaveGameStorageValues);
}
26 changes: 25 additions & 1 deletion src/luaitemtype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,18 @@ int luaItemTypeGetHitChance(lua_State* L)
return 1;
}

int luaItemTypeGetMaxHitChance(lua_State* L)
{
// itemType:getMaxHitChance()
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
if (itemType) {
lua_pushinteger(L, itemType->maxHitChance);
} else {
lua_pushnil(L);
}
return 1;
}

int luaItemTypeGetShootRange(lua_State* L)
{
// itemType:getShootRange()
Expand Down Expand Up @@ -522,10 +534,12 @@ int luaItemTypeGetAbilities(lua_State* L)
ItemType* itemType = getUserdata<ItemType>(L, 1);
if (itemType) {
Abilities& abilities = itemType->getAbilities();
lua_createtable(L, 10, 12);
lua_createtable(L, 12, 13);
setField(L, "healthGain", abilities.healthGain);
setField(L, "healthGainPercent", abilities.healthGainPercent);
setField(L, "healthTicks", abilities.healthTicks);
setField(L, "manaGain", abilities.manaGain);
setField(L, "manaGainPercent", abilities.manaGainPercent);
setField(L, "manaTicks", abilities.manaTicks);
setField(L, "conditionImmunities", abilities.conditionImmunities);
setField(L, "conditionSuppressions", abilities.conditionSuppressions);
Expand Down Expand Up @@ -619,6 +633,15 @@ int luaItemTypeGetAbilities(lua_State* L)
lua_rawseti(L, -2, i + 1);
}
lua_setfield(L, -2, "reflectPercent");

// Experience Rates
lua_createtable(L, 0, static_cast<size_t>(ExperienceRateType::BONUS));
for (uint8_t e = static_cast<uint8_t>(ExperienceRateType::BASE);
e <= static_cast<uint8_t>(ExperienceRateType::STAMINA); e++) {
lua_pushinteger(L, abilities.experienceRate[e]);
lua_rawseti(L, -2, e);
}
lua_setfield(L, -2, "experienceRate");
}
return 1;
}
Expand Down Expand Up @@ -927,6 +950,7 @@ void LuaScriptInterface::registerItemType()
registerMethod("ItemType", "getStackSize", luaItemTypeGetStackSize);

registerMethod("ItemType", "getHitChance", luaItemTypeGetHitChance);
registerMethod("ItemType", "getMaxHitChance", luaItemTypeGetHitChance);
registerMethod("ItemType", "getShootRange", luaItemTypeGetShootRange);

registerMethod("ItemType", "getAttack", luaItemTypeGetAttack);
Expand Down
Loading

0 comments on commit a8a38e5

Please sign in to comment.