From fef55792f5aa1ecab4dfdedacf2801a9884fe00c Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Sun, 27 Oct 2024 00:26:27 -0300
Subject: [PATCH 01/28] init
Delete testByte.lua
---
config.lua.dist | 3 +-
data-otservbr-global/migrations/46.lua | 27 +-
data-otservbr-global/migrations/47.lua | 3 +
data-otservbr-global/world/otservbr-house.xml | 1970 ++++++++---------
.../globalevents/server_initialization.lua | 24 -
data/scripts/talkactions/player/buy_house.lua | 8 +-
.../talkactions/player/leave_house.lua | 8 +-
.../scripts/talkactions/player/sell_house.lua | 8 +-
schema.sql | 13 +-
src/account/account.cpp | 7 +
src/account/account.hpp | 3 +
src/account/account_info.hpp | 1 +
src/account/account_repository_db.cpp | 5 +-
src/config/config_enums.hpp | 1 +
src/config/configmanager.cpp | 1 +
src/creatures/players/player.cpp | 35 +
src/creatures/players/player.hpp | 17 +
src/enums/player_cyclopedia.hpp | 21 +
src/game/game.cpp | 177 +-
src/game/game.hpp | 6 +
src/io/iologindata.cpp | 8 -
src/io/iologindata.hpp | 1 -
src/io/iomapserialize.cpp | 55 +-
src/lua/functions/map/house_functions.cpp | 2 +-
src/map/house/house.cpp | 105 +-
src/map/house/house.hpp | 104 +
src/server/network/protocol/protocolgame.cpp | 127 ++
src/server/network/protocol/protocolgame.hpp | 5 +
28 files changed, 1682 insertions(+), 1063 deletions(-)
create mode 100644 data-otservbr-global/migrations/47.lua
diff --git a/config.lua.dist b/config.lua.dist
index 4d28a2033cd..5f5c128a4e4 100644
--- a/config.lua.dist
+++ b/config.lua.dist
@@ -344,9 +344,10 @@ Setting this to false may pose risks; if a house is abandoned and contains a lar
]]
-- Periods: daily/weekly/monthly/yearly/never
-- Base: sqm,rent,sqm+rent
+toggleCyclopediaHouseAuction = true
housePriceRentMultiplier = 0.0
housePriceEachSQM = 1000
-houseRentPeriod = "never"
+houseRentPeriod = "monthly"
houseRentRate = 1.0
houseOwnedByAccount = false
houseBuyLevel = 100
diff --git a/data-otservbr-global/migrations/46.lua b/data-otservbr-global/migrations/46.lua
index 86a6d8ffec1..600bb3785ad 100644
--- a/data-otservbr-global/migrations/46.lua
+++ b/data-otservbr-global/migrations/46.lua
@@ -1,3 +1,28 @@
function onUpdateDatabase()
- return false -- true = There are others migrations file | false = this is the last migration file
+ logger.info("Updating database to version 44 (House Auction)")
+
+ db.query([[
+ ALTER TABLE `houses`
+ DROP `bid`,
+ DROP `bid_end`,
+ DROP `last_bid`,
+ DROP `highest_bidder`
+ ]])
+
+ db.query([[
+ ALTER TABLE `houses`
+ ADD `bidder` int(11) NOT NULL DEFAULT '0',
+ ADD `bidder_name` varchar(255) NOT NULL DEFAULT '',
+ ADD `highest_bid` int(11) NOT NULL DEFAULT '0',
+ ADD `internal_bid` int(11) NOT NULL DEFAULT '0',
+ ADD `bid_end_date` int(11) NOT NULL DEFAULT '0',
+ ADD `state` smallint(5) UNSIGNED NOT NULL DEFAULT '0'
+ ]])
+
+ db.query([[
+ ALTER TABLE `accounts`
+ ADD `house_bid_id` int(11) NOT NULL DEFAULT '0'
+ ]])
+
+ return true
end
diff --git a/data-otservbr-global/migrations/47.lua b/data-otservbr-global/migrations/47.lua
new file mode 100644
index 00000000000..86a6d8ffec1
--- /dev/null
+++ b/data-otservbr-global/migrations/47.lua
@@ -0,0 +1,3 @@
+function onUpdateDatabase()
+ return false -- true = There are others migrations file | false = this is the last migration file
+end
diff --git a/data-otservbr-global/world/otservbr-house.xml b/data-otservbr-global/world/otservbr-house.xml
index 7eff23b4606..bedef70ff1f 100644
--- a/data-otservbr-global/world/otservbr-house.xml
+++ b/data-otservbr-global/world/otservbr-house.xml
@@ -1,987 +1,987 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data/scripts/globalevents/server_initialization.lua b/data/scripts/globalevents/server_initialization.lua
index df29660d373..a58cf01d3a2 100644
--- a/data/scripts/globalevents/server_initialization.lua
+++ b/data/scripts/globalevents/server_initialization.lua
@@ -27,29 +27,6 @@ local function moveExpiredBansToHistory()
end
end
--- Function to check and process house auctions
-local function processHouseAuctions()
- local resultId = db.storeQuery("SELECT `id`, `highest_bidder`, `last_bid`, " .. "(SELECT `balance` FROM `players` WHERE `players`.`id` = `highest_bidder`) AS `balance` " .. "FROM `houses` WHERE `owner` = 0 AND `bid_end` != 0 AND `bid_end` < " .. os.time())
- if resultId then
- repeat
- local house = House(Result.getNumber(resultId, "id"))
- if house then
- local highestBidder = Result.getNumber(resultId, "highest_bidder")
- local balance = Result.getNumber(resultId, "balance")
- local lastBid = Result.getNumber(resultId, "last_bid")
- if balance >= lastBid then
- db.query("UPDATE `players` SET `balance` = " .. (balance - lastBid) .. " WHERE `id` = " .. highestBidder)
- house:setHouseOwner(highestBidder)
- end
-
- db.asyncQuery("UPDATE `houses` SET `last_bid` = 0, `bid_end` = 0, `highest_bidder` = 0, `bid` = 0 " .. "WHERE `id` = " .. house:getId())
- end
- until not Result.next(resultId)
-
- Result.free(resultId)
- end
-end
-
-- Function to store towns in the database
local function storeTownsInDatabase()
db.query("TRUNCATE TABLE `towns`")
@@ -150,7 +127,6 @@ function serverInitialization.onStartup()
cleanupDatabase()
moveExpiredBansToHistory()
- processHouseAuctions()
storeTownsInDatabase()
checkAndLogDuplicateValues({ "Global", "GlobalStorage", "Storage" })
updateEventRates()
diff --git a/data/scripts/talkactions/player/buy_house.lua b/data/scripts/talkactions/player/buy_house.lua
index c3784d81a6b..84d3a34aad0 100644
--- a/data/scripts/talkactions/player/buy_house.lua
+++ b/data/scripts/talkactions/player/buy_house.lua
@@ -60,6 +60,8 @@ function buyHouse.onSay(player, words, param)
return true
end
-buyHouse:separator(" ")
-buyHouse:groupType("normal")
-buyHouse:register()
+if not configManager.getBoolean(configKeys.CYCLOPEDIA_HOUSE_AUCTION) then
+ buyHouse:separator(" ")
+ buyHouse:groupType("normal")
+ buyHouse:register()
+end
diff --git a/data/scripts/talkactions/player/leave_house.lua b/data/scripts/talkactions/player/leave_house.lua
index 20ad186f2d2..d954eb1dcf0 100644
--- a/data/scripts/talkactions/player/leave_house.lua
+++ b/data/scripts/talkactions/player/leave_house.lua
@@ -42,6 +42,8 @@ function leaveHouse.onSay(player, words, param)
return true
end
-leaveHouse:separator(" ")
-leaveHouse:groupType("normal")
-leaveHouse:register()
+if not configManager.getBoolean(configKeys.CYCLOPEDIA_HOUSE_AUCTION) then
+ leaveHouse:separator(" ")
+ leaveHouse:groupType("normal")
+ leaveHouse:register()
+end
diff --git a/data/scripts/talkactions/player/sell_house.lua b/data/scripts/talkactions/player/sell_house.lua
index c96cb5f71c3..dadadd066d1 100644
--- a/data/scripts/talkactions/player/sell_house.lua
+++ b/data/scripts/talkactions/player/sell_house.lua
@@ -20,6 +20,8 @@ function sellHouse.onSay(player, words, param)
return true
end
-sellHouse:separator(" ")
-sellHouse:groupType("normal")
-sellHouse:register()
+if not configManager.getBoolean(configKeys.CYCLOPEDIA_HOUSE_AUCTION) then
+ sellHouse:separator(" ")
+ sellHouse:groupType("normal")
+ sellHouse:register()
+end
diff --git a/schema.sql b/schema.sql
index af245067057..821b3bcff41 100644
--- a/schema.sql
+++ b/schema.sql
@@ -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', '46'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');
+INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '47'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');
-- Table structure `accounts`
CREATE TABLE IF NOT EXISTS `accounts` (
@@ -24,6 +24,7 @@ CREATE TABLE IF NOT EXISTS `accounts` (
`tournament_coins` int(12) UNSIGNED NOT NULL DEFAULT '0',
`creation` int(11) UNSIGNED NOT NULL DEFAULT '0',
`recruiter` INT(6) DEFAULT 0,
+ `house_bid_id` int(11) NOT NULL DEFAULT '0',
CONSTRAINT `accounts_pk` PRIMARY KEY (`id`),
CONSTRAINT `accounts_unique` UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -451,13 +452,15 @@ CREATE TABLE IF NOT EXISTS `houses` (
`name` varchar(255) NOT NULL,
`rent` int(11) NOT NULL DEFAULT '0',
`town_id` int(11) NOT NULL DEFAULT '0',
- `bid` int(11) NOT NULL DEFAULT '0',
- `bid_end` int(11) NOT NULL DEFAULT '0',
- `last_bid` int(11) NOT NULL DEFAULT '0',
- `highest_bidder` int(11) NOT NULL DEFAULT '0',
`size` int(11) NOT NULL DEFAULT '0',
`guildid` int(11),
`beds` int(11) NOT NULL DEFAULT '0',
+ `bidder` int(11) NOT NULL DEFAULT '0',
+ `bidder_name` varchar(255) NOT NULL DEFAULT '',
+ `highest_bid` int(11) NOT NULL DEFAULT '0',
+ `internal_bid` int(11) NOT NULL DEFAULT '0',
+ `bid_end_date` int(11) NOT NULL DEFAULT '0',
+ `state` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
INDEX `owner` (`owner`),
INDEX `town_id` (`town_id`),
CONSTRAINT `houses_pk` PRIMARY KEY (`id`)
diff --git a/src/account/account.cpp b/src/account/account.cpp
index 2cd411ef3e7..60b78c0f0ac 100644
--- a/src/account/account.cpp
+++ b/src/account/account.cpp
@@ -296,3 +296,10 @@ uint32_t Account::getAccountAgeInDays() const {
[[nodiscard]] time_t Account::getPremiumLastDay() const {
return m_account.premiumLastDay;
}
+
+uint32_t Account::getHouseBidId() const {
+ return m_account.houseBidId;
+}
+void Account::setHouseBidId(uint32_t houseId) {
+ m_account.houseBidId = houseId;
+}
diff --git a/src/account/account.hpp b/src/account/account.hpp
index d968ba8ddfb..2820050ded5 100644
--- a/src/account/account.hpp
+++ b/src/account/account.hpp
@@ -112,6 +112,9 @@ class Account {
std::tuple, uint8_t> getAccountPlayers() const;
+ void setHouseBidId(uint32_t houseId);
+ uint32_t getHouseBidId() const;
+
// Old protocol compat
void setProtocolCompat(bool toggle);
diff --git a/src/account/account_info.hpp b/src/account/account_info.hpp
index 698c3b96c1c..ea4198b98a4 100644
--- a/src/account/account_info.hpp
+++ b/src/account/account_info.hpp
@@ -24,4 +24,5 @@ struct AccountInfo {
time_t sessionExpires = 0;
uint32_t premiumDaysPurchased = 0;
uint32_t creationTime = 0;
+ uint32_t houseBidId = 0;
};
diff --git a/src/account/account_repository_db.cpp b/src/account/account_repository_db.cpp
index 10f3d6f3a41..64e90619304 100644
--- a/src/account/account_repository_db.cpp
+++ b/src/account/account_repository_db.cpp
@@ -44,13 +44,14 @@ bool AccountRepositoryDB::loadBySession(const std::string &sessionKey, AccountIn
bool AccountRepositoryDB::save(const AccountInfo &accInfo) {
bool successful = g_database().executeQuery(
fmt::format(
- "UPDATE `accounts` SET `type` = {}, `premdays` = {}, `lastday` = {}, `creation` = {}, `premdays_purchased` = {} WHERE `id` = {}",
+ "UPDATE `accounts` SET `type` = {}, `premdays` = {}, `lastday` = {}, `creation` = {}, `premdays_purchased` = {}, `house_bid_id` = {} WHERE `id` = {}",
accInfo.accountType,
accInfo.premiumRemainingDays,
accInfo.premiumLastDay,
accInfo.creationTime,
accInfo.premiumDaysPurchased,
- accInfo.id
+ accInfo.id,
+ accInfo.houseBidId
)
);
diff --git a/src/config/config_enums.hpp b/src/config/config_enums.hpp
index 559045fdb9b..a3294d692dc 100644
--- a/src/config/config_enums.hpp
+++ b/src/config/config_enums.hpp
@@ -46,6 +46,7 @@ enum ConfigKey_t : uint16_t {
CONVERT_UNSAFE_SCRIPTS,
CORE_DIRECTORY,
CRITICALCHANCE,
+ CYCLOPEDIA_HOUSE_AUCTION,
DATA_DIRECTORY,
DAY_KILLS_TO_RED,
DEATH_LOSE_PERCENT,
diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp
index aa028b52284..f5bafa4fbc3 100644
--- a/src/config/configmanager.cpp
+++ b/src/config/configmanager.cpp
@@ -155,6 +155,7 @@ bool ConfigManager::load() {
loadBoolConfig(L, VIP_SYSTEM_ENABLED, "vipSystemEnabled", false);
loadBoolConfig(L, WARN_UNSAFE_SCRIPTS, "warnUnsafeScripts", true);
loadBoolConfig(L, XP_DISPLAY_MODE, "experienceDisplayRates", true);
+ loadBoolConfig(L, CYCLOPEDIA_HOUSE_AUCTION, "toggleCyclopediaHouseAuction", true);
loadFloatConfig(L, BESTIARY_RATE_CHARM_SHOP_PRICE, "bestiaryRateCharmShopPrice", 1.0);
loadFloatConfig(L, COMBAT_CHAIN_SKILL_FORMULA_AXE, "combatChainSkillFormulaAxe", 0.9);
diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp
index 59d1d6a718a..4487523f395 100644
--- a/src/creatures/players/player.cpp
+++ b/src/creatures/players/player.cpp
@@ -8232,3 +8232,38 @@ uint16_t Player::getPlayerVocationEnum() const {
return Vocation_t::VOCATION_NONE;
}
+
+BidErrorMessage Player::canBidHouse(uint32_t houseId) {
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house) {
+ return BidErrorMessage::Internal;
+ }
+
+ if (getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
+ return BidErrorMessage::Rookgaard;
+ }
+
+ if (!isPremium()) {
+ return BidErrorMessage::Premium;
+ }
+
+ if (getAccount()->getHouseBidId() != 0) {
+ return BidErrorMessage::OnlyOneBid;
+ }
+
+ if (getBankBalance() < (house->getRent() + house->getHighestBid())) {
+ return BidErrorMessage::NotEnoughMoney;
+ }
+
+ if (house->isGuildhall()) {
+ if (getGuildRank() && getGuildRank()->level != 3) {
+ return BidErrorMessage::Guildhall;
+ }
+
+ if (getGuild() && getGuild()->getBankBalance() < (house->getRent() + house->getHighestBid())) {
+ return BidErrorMessage::NotEnoughGuildMoney;
+ }
+ }
+
+ return BidErrorMessage::NoError;
+}
\ No newline at end of file
diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp
index cd69cec99a0..dedf6b9d119 100644
--- a/src/creatures/players/player.hpp
+++ b/src/creatures/players/player.hpp
@@ -1582,6 +1582,23 @@ class Player final : public Creature, public Cylinder, public Bankable {
client->sendOutfitWindow();
}
}
+
+ BidErrorMessage canBidHouse(uint32_t houseId);
+ void sendCyclopediaHouseList(HouseMap houses) {
+ if (client) {
+ client->sendCyclopediaHouseList(houses);
+ }
+ }
+ void sendResourceBalance(Resource_t resourceType, uint64_t value) {
+ if (client) {
+ client->sendResourceBalance(resourceType, value);
+ }
+ }
+ void sendHouseAuctionMessage(uint32_t houseId, HouseAuctionType type, uint8_t index, bool bidSuccess = false) {
+ if (client) {
+ client->sendHouseAuctionMessage(houseId, type, index, bidSuccess);
+ }
+ }
// Imbuements
void onApplyImbuement(Imbuement* imbuement, std::shared_ptr- item, uint8_t slot, bool protectionCharm);
void onClearImbuement(std::shared_ptr
- item, uint8_t slot);
diff --git a/src/enums/player_cyclopedia.hpp b/src/enums/player_cyclopedia.hpp
index 295e573984f..fb2a97dac13 100644
--- a/src/enums/player_cyclopedia.hpp
+++ b/src/enums/player_cyclopedia.hpp
@@ -60,3 +60,24 @@ enum class CyclopediaMapData_t : uint8_t {
Donations = 9,
SetCurrentArea = 10,
};
+
+enum class HouseAuctionType : uint8_t {
+ Bid = 1,
+ MoveOut = 2,
+};
+
+enum class BidSuccessMessage : uint8_t {
+ BidSuccess = 0,
+ LowerBid = 1,
+};
+
+enum class BidErrorMessage : uint8_t {
+ NoError = 0,
+ Rookgaard = 3,
+ Premium = 5,
+ Guildhall = 6,
+ OnlyOneBid = 7,
+ NotEnoughMoney = 17,
+ NotEnoughGuildMoney = 21,
+ Internal = 24,
+};
\ No newline at end of file
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 00a81c63e78..18281b3bc51 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10241,15 +10241,18 @@ bool Game::removeFiendishMonster(uint32_t id, bool create /* = true*/) {
}
void Game::updateForgeableMonsters() {
- forgeableMonsters.clear();
- for (const auto &[monsterId, monster] : monsters) {
- auto monsterTile = monster->getTile();
- if (!monsterTile) {
- continue;
- }
+ if (auto influencedLimit = g_configManager().getNumber(FORGE_INFLUENCED_CREATURES_LIMIT, __FUNCTION__);
+ forgeableMonsters.size() < influencedLimit * 2) {
+ forgeableMonsters.clear();
+ for (const auto &[monsterId, monster] : monsters) {
+ auto monsterTile = monster->getTile();
+ if (!monsterTile) {
+ continue;
+ }
- if (monster->canBeForgeMonster() && !monsterTile->hasFlag(TILESTATE_NOLOGOUT)) {
- forgeableMonsters.push_back(monster->getID());
+ if (monster->canBeForgeMonster() && !monsterTile->hasFlag(TILESTATE_NOLOGOUT)) {
+ forgeableMonsters.push_back(monster->getID());
+ }
}
}
@@ -10736,3 +10739,161 @@ const std::unordered_map &Game::getHirelingSkills() {
const std::unordered_map &Game::getHirelingOutfits() {
return m_hirelingOutfits;
}
+
+void Game::playerCyclopediaHousesByTown(uint32_t playerId, const std::string townName) {
+ std::shared_ptr player = getPlayerByID(playerId);
+ if (!player) {
+ return;
+ }
+
+ HouseMap houses;
+ if (!townName.empty()) {
+ const auto& housesList = g_game().map.houses.getHouses();
+ for (const auto& it : housesList) {
+ const auto& house = it.second;
+ const auto& town = g_game().map.towns.getTown(house->getTownId());
+ if (!town) {
+ return;
+ }
+
+ const std::string houseTown = town->getName();
+ if (houseTown == townName) {
+ houses.emplace(house->getClientId(), house);
+ }
+ }
+ } else {
+ auto playerHouses = g_game().map.houses.getAllHousesByPlayerId(player->getGUID());
+ if (playerHouses.size()) {
+ for (const auto playerHouse : playerHouses) {
+ if (!playerHouse) {
+ continue;
+ }
+ houses.emplace(playerHouse->getClientId(), playerHouse);
+ }
+ } else {
+ const auto house = g_game().map.houses.getHouseByBidderName(player->getName());
+ if (house) {
+ houses.emplace(house->getClientId(), house);
+ }
+ }
+ }
+ player->sendCyclopediaHouseList(houses);
+}
+
+void Game::playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_t bidValue) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION, __FUNCTION__)) {
+ return;
+ }
+
+ std::shared_ptr player = getPlayerByID(playerId);
+ if (!player) {
+ return;
+ }
+
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house) {
+ return;
+ }
+
+ auto ret = player->canBidHouse(houseId);
+ if (ret != BidErrorMessage::NoError) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::Bid, enumToValue(ret));
+ }
+ ret = BidErrorMessage::NotEnoughMoney;
+ auto retSuccess = BidSuccessMessage::BidSuccess;
+
+ if(house->getBidderName().empty()) {
+ if (!processBankAuction(player, house, bidValue)) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::Bid, enumToValue(ret));
+ return;
+ }
+ house->setHighestBid(0);
+ house->setInternalBid(bidValue);
+ house->setBidHolderLimit(bidValue);
+ house->setBidderName(player->getName());
+ house->setBidder(player->getGUID());
+ house->calculateBidEndDate(1);
+ } else if (house->getBidderName() == player->getName()) {
+ if (!processBankAuction(player, house, bidValue, true)) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::Bid, enumToValue(ret));
+ return;
+ }
+ house->setInternalBid(bidValue);
+ house->setBidHolderLimit(bidValue);
+ } else if (bidValue <= house->getInternalBid()) {
+ house->setHighestBid(bidValue);
+ retSuccess = BidSuccessMessage::LowerBid;
+ } else {
+ if (!processBankAuction(player, house, bidValue)) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::Bid, enumToValue(ret));
+ return;
+ }
+ house->setHighestBid(house->getInternalBid() + 1);
+ house->setInternalBid(bidValue);
+ house->setBidHolderLimit(bidValue);
+ house->setBidderName(player->getName());
+ house->setBidder(player->getGUID());
+ }
+
+ const auto& town = g_game().map.towns.getTown(house->getTownId());
+ if (!town) {
+ return;
+ }
+
+ const std::string houseTown = town->getName();
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::Bid, enumToValue(retSuccess), true);
+ playerCyclopediaHousesByTown(playerId, houseTown);
+}
+
+void Game::playerCyclopediaHouseLeave(uint32_t playerId, uint32_t houseId, uint32_t timestamp) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION, __FUNCTION__)) {
+ return;
+ }
+
+ std::shared_ptr player = getPlayerByID(playerId);
+ if (!player) {
+ return;
+ }
+
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house || house->getOwner() != player->getGUID()) {
+ return;
+ }
+
+ house->setBidEndDate(timestamp);
+ house->setBidder(-1);
+
+ playerCyclopediaHousesByTown(playerId, "");
+}
+
+bool Game::processBankAuction(std::shared_ptr player, std::shared_ptr house, uint64_t bid, bool replace /* = false*/) {
+ if (!replace && player->getBankBalance() < (house->getRent() + bid)) {
+ return false;
+ }
+
+ if (player->getBankBalance() < bid) {
+ return false;
+ }
+
+ uint64_t balance = player->getBankBalance();
+ if (replace) {
+ player->setBankBalance(balance - (bid - house->getInternalBid()));
+ } else {
+ player->setBankBalance(balance - (house->getRent() + bid));
+ }
+
+ player->sendResourceBalance(RESOURCE_BANK, player->getBankBalance());
+
+ if (house->getBidderName() != player->getName()) {
+ const auto otherPlayer = g_game().getPlayerByName(house->getBidderName());
+ if (!otherPlayer) {
+ uint32_t bidderGuid = IOLoginData::getGuidByName(house->getBidderName());
+ IOLoginData::increaseBankBalance(bidderGuid, (house->getBidHolderLimit() + house->getRent()));
+ } else {
+ otherPlayer->setBankBalance(otherPlayer->getBankBalance() + (house->getBidHolderLimit() + house->getRent()));
+ otherPlayer->sendResourceBalance(RESOURCE_BANK, otherPlayer->getBankBalance());
+ }
+ }
+
+ return true;
+}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index e04dbb26cff..1b0b9b369d3 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -315,6 +315,12 @@ class Game {
void playerHighscores(std::shared_ptr player, HighscoreType_t type, uint8_t category, uint32_t vocation, const std::string &worldName, uint16_t page, uint8_t entriesPerPage);
static std::string getSkillNameById(uint8_t &skill);
+ // House Auction
+ void playerCyclopediaHousesByTown(uint32_t playerId, const std::string townName);
+ void playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_t bidValue);
+ void playerCyclopediaHouseLeave(uint32_t playerId, uint32_t houseId, uint32_t timestamp);
+ bool processBankAuction(std::shared_ptr player, std::shared_ptr house, uint64_t bid, bool replace = false);
+
void updatePlayerSaleItems(uint32_t playerId);
bool internalStartTrade(std::shared_ptr player, std::shared_ptr partner, std::shared_ptr
- tradeItem);
diff --git a/src/io/iologindata.cpp b/src/io/iologindata.cpp
index 17816f969de..4548a1c91fa 100644
--- a/src/io/iologindata.cpp
+++ b/src/io/iologindata.cpp
@@ -350,14 +350,6 @@ void IOLoginData::increaseBankBalance(uint32_t guid, uint64_t bankBalance) {
Database::getInstance().executeQuery(query.str());
}
-bool IOLoginData::hasBiddedOnHouse(uint32_t guid) {
- Database &db = Database::getInstance();
-
- std::ostringstream query;
- query << "SELECT `id` FROM `houses` WHERE `highest_bidder` = " << guid << " LIMIT 1";
- return db.storeQuery(query.str()).get() != nullptr;
-}
-
std::vector IOLoginData::getVIPEntries(uint32_t accountId) {
std::string query = fmt::format("SELECT `player_id`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `name`, `description`, `icon`, `notify` FROM `account_viplist` WHERE `account_id` = {}", accountId);
std::vector entries;
diff --git a/src/io/iologindata.hpp b/src/io/iologindata.hpp
index 79fa3b59ad7..058fd8c4a98 100644
--- a/src/io/iologindata.hpp
+++ b/src/io/iologindata.hpp
@@ -29,7 +29,6 @@ class IOLoginData {
static std::string getNameByGuid(uint32_t guid);
static bool formatPlayerName(std::string &name);
static void increaseBankBalance(uint32_t guid, uint64_t bankBalance);
- static bool hasBiddedOnHouse(uint32_t guid);
static std::vector getVIPEntries(uint32_t accountId);
static void addVIPEntry(uint32_t accountId, uint32_t guid, const std::string &description, uint32_t icon, bool notify);
diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp
index 220b50a85e6..41087ed202a 100644
--- a/src/io/iomapserialize.cpp
+++ b/src/io/iomapserialize.cpp
@@ -273,7 +273,7 @@ void IOMapSerialize::saveTile(PropWriteStream &stream, std::shared_ptr til
bool IOMapSerialize::loadHouseInfo() {
Database &db = Database::getInstance();
- DBResult_ptr result = db.storeQuery("SELECT `id`, `owner`, `new_owner`, `paid`, `warnings` FROM `houses`");
+ DBResult_ptr result = db.storeQuery("SELECT `id`, `owner`, `new_owner`, `bidder`, `bidder_name`, `highest_bid`, `internal_bid`, `bid_end_date`, `state` FROM `houses`");
if (!result) {
return false;
}
@@ -284,6 +284,13 @@ bool IOMapSerialize::loadHouseInfo() {
if (house) {
uint32_t owner = result->getNumber("owner");
int32_t newOwner = result->getNumber("new_owner");
+ uint32_t bidder = result->getNumber("bidder");
+ std::string bidderName = result->getString("bidder_name");
+ uint32_t highestBid = result->getNumber("highest_bid");
+ uint32_t internalBid = result->getNumber("internal_bid");
+ uint32_t bidEndDate = result->getNumber("bid_end_date");
+ uint32_t state = result->getNumber("state");
+ const auto timeNow = OTSYS_TIME(true);
// Transfer house owner
auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART);
if (isTransferOnRestart && newOwner >= 0) {
@@ -295,11 +302,32 @@ bool IOMapSerialize::loadHouseInfo() {
g_logger().debug("Setting house id '{}' owner to player GUID '{}'", houseId, newOwner);
house->setOwner(newOwner);
}
+ } else if (state == 0 && bidder > 0 && timeNow > bidEndDate) {
+ if (highestBid < internalBid) {
+ uint32_t diff = internalBid - highestBid;
+ IOLoginData::increaseBankBalance(bidder, diff);
+ }
+ g_logger().debug("Setting house id '{}' owner to player GUID '{}'", houseId, bidder);
+ house->setOwner(bidder);
+ bidder = 0;
+ bidderName = "";
+ highestBid = 0;
+ internalBid = 0;
+ bidEndDate = 0;
+ } else if (state == 2 && bidder == -1 && timeNow > bidEndDate) {
+ g_logger().debug("Removing house id '{}' owner", houseId);
+ house->setOwner(0);
+ bidEndDate = 0;
+ bidder = 0;
} else {
house->setOwner(owner, false);
}
- house->setPaidUntil(result->getNumber("paid"));
- house->setPayRentWarnings(result->getNumber("warnings"));
+ house->setBidder(bidder);
+ house->setBidderName(bidderName);
+ house->setHighestBid(highestBid);
+ house->setInternalBid(internalBid);
+ house->setBidHolderLimit(internalBid);
+ house->setBidEndDate(bidEndDate);
}
} while (result->next());
@@ -331,11 +359,26 @@ bool IOMapSerialize::SaveHouseInfoGuard() {
Database &db = Database::getInstance();
std::ostringstream query;
- DBInsert houseUpdate("INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`) VALUES ");
- houseUpdate.upsert({ "owner", "paid", "warnings", "name", "town_id", "rent", "size", "beds" });
+ DBInsert houseUpdate("INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`, `bidder`, `bidder_name`, `highest_bid`, `internal_bid`, `bid_end_date`, `state`) VALUES ");
+ houseUpdate.upsert({ "owner", "paid", "warnings", "name", "town_id", "rent", "size", "beds", "bidder", "bidder_name", "highest_bid", "internal_bid", "bid_end_date", "state" });
for (const auto &[key, house] : g_game().map.houses.getHouses()) {
- std::string values = fmt::format("{},{},{},{},{},{},{},{},{}", house->getId(), house->getOwner(), house->getPaidUntil(), house->getPayRentWarnings(), db.escapeString(house->getName()), house->getTownId(), house->getRent(), house->getSize(), house->getBedCount());
+ std::string values = fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}",
+ house->getId(),
+ house->getOwner(),
+ house->getPaidUntil(),
+ house->getPayRentWarnings(),
+ db.escapeString(house->getName()),
+ house->getTownId(), house->getRent(),
+ house->getSize(),
+ house->getBedCount(),
+ house->getBidder(),
+ db.escapeString(house->getBidderName()),
+ house->getHighestBid(),
+ house->getInternalBid(),
+ house->getBidEndDate(),
+ house->getState()
+ );
if (!houseUpdate.addRow(values)) {
return false;
diff --git a/src/lua/functions/map/house_functions.cpp b/src/lua/functions/map/house_functions.cpp
index 597eec3975e..c9edf0c970a 100644
--- a/src/lua/functions/map/house_functions.cpp
+++ b/src/lua/functions/map/house_functions.cpp
@@ -197,7 +197,7 @@ int HouseFunctions::luaHouseStartTrade(lua_State* L) {
return 1;
}
- if (IOLoginData::hasBiddedOnHouse(tradePartner->getGUID())) {
+ if (tradePartner->getAccount()->getHouseBidId() != 0) {
lua_pushnumber(L, RETURNVALUE_TRADEPLAYERHIGHESTBIDDER);
return 1;
}
diff --git a/src/map/house/house.cpp b/src/map/house/house.cpp
index 9995862c679..c7530187df1 100644
--- a/src/map/house/house.cpp
+++ b/src/map/house/house.cpp
@@ -90,7 +90,7 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, std::shared
Database &db = Database::getInstance();
std::ostringstream query;
- query << "UPDATE `houses` SET `owner` = " << guid << ", `new_owner` = -1, `bid` = 0, `bid_end` = 0, `last_bid` = 0, `highest_bidder` = 0 WHERE `id` = " << id;
+ query << "UPDATE `houses` SET `owner` = " << guid << ", `new_owner` = -1, `paid` = 0, `bidder` = 0, `bidder_name` = '', `highest_bid` = 0, `internal_bid` = 0, `bid_end_date` = 0, `state` = 0 WHERE `id` = " << id;
db.executeQuery(query.str());
}
@@ -102,8 +102,10 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, std::shared
if (owner != 0) {
tryTransferOwnership(std::move(player), false);
- } else {
- std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD));
+ }
+
+ if (guid != 0) {
+ std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD, __FUNCTION__));
time_t currentTime = time(nullptr);
if (strRentPeriod == "yearly") {
currentTime += 24 * 60 * 60 * 365;
@@ -118,6 +120,8 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, std::shared
}
paidUntil = currentTime;
+ } else {
+ paidUntil = 0;
}
rentWarnings = 0;
@@ -136,6 +140,7 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, std::shared
owner = guid;
ownerName = name;
ownerAccountId = result->getNumber("account_id");
+ state = 2;
}
}
@@ -150,15 +155,17 @@ void House::updateDoorDescription() const {
ss << "It belongs to house '" << houseName << "'. Nobody owns this house.";
}
- ss << " It is " << getSize() << " square meters.";
- const int32_t housePrice = getPrice();
- if (housePrice != -1) {
- if (g_configManager().getBoolean(HOUSE_PURSHASED_SHOW_PRICE) || owner == 0) {
- ss << " It costs " << formatNumber(getPrice()) << " gold coins.";
- }
- std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD));
- if (strRentPeriod != "never") {
- ss << " The rent cost is " << formatNumber(getRent()) << " gold coins and it is billed " << strRentPeriod << ".";
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION, __FUNCTION__)) {
+ ss << " It is " << getSize() << " square meters.";
+ const int32_t housePrice = getPrice();
+ if (housePrice != -1) {
+ if (g_configManager().getBoolean(HOUSE_PURSHASED_SHOW_PRICE, __FUNCTION__) || owner == 0) {
+ ss << " It costs " << formatNumber(getPrice()) << " gold coins.";
+ }
+ std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD, __FUNCTION__));
+ if (strRentPeriod != "never") {
+ ss << " The rent cost is " << formatNumber(getRent()) << " gold coins and it is billed " << strRentPeriod << ".";
+ }
}
}
@@ -474,6 +481,43 @@ void House::resetTransferItem() {
}
}
+void House::calculateBidEndDate(uint8_t daysToEnd) {
+ auto currentTimeMs = std::chrono::system_clock::now().time_since_epoch();
+
+ std::chrono::system_clock::time_point now = std::chrono::system_clock::time_point(
+ std::chrono::duration_cast(currentTimeMs)
+ );
+
+ // Truncate to whole days since epoch
+ days daysSinceEpoch = std::chrono::duration_cast(now.time_since_epoch());
+
+ // Get today's date at 00:00:00 UTC
+ std::chrono::system_clock::time_point todayMidnight = std::chrono::system_clock::time_point(daysSinceEpoch);
+
+ std::chrono::system_clock::time_point targetDay = todayMidnight + days(daysToEnd);
+
+ const auto serverSaveTime = g_configManager().getString(GLOBAL_SERVER_SAVE_TIME, __FUNCTION__);
+
+ std::vector params = vectorAtoi(explodeString(serverSaveTime, ":"));
+ int32_t hour = params.front();
+ int32_t min = 0;
+ int32_t sec = 0;
+ if (params.size() > 1) {
+ min = params[1];
+
+ if (params.size() > 2) {
+ sec = params[2];
+ }
+ }
+ std::chrono::system_clock::time_point targetTime = targetDay + std::chrono::hours(hour) + std::chrono::minutes(min) + std::chrono::seconds(sec);
+
+ std::time_t resultTime = std::chrono::system_clock::to_time_t(targetTime);
+ std::tm* localTime = std::localtime(&resultTime);
+ uint32_t bidEndDate = static_cast(std::mktime(localTime));
+
+ this->bidEndDate = bidEndDate;
+}
+
std::shared_ptr HouseTransferItem::createHouseTransferItem(std::shared_ptr house) {
std::shared_ptr transferItem = std::make_shared(house);
transferItem->setID(ITEM_DOCUMENT_RO);
@@ -720,6 +764,35 @@ std::shared_ptr Houses::getHouseByPlayerId(uint32_t playerId) {
return nullptr;
}
+std::vector> Houses::getAllHousesByPlayerId(uint32_t playerId) {
+ std::vector> playerHouses;
+ for (const auto &it : houseMap) {
+ if (it.second->getOwner() == playerId) {
+ playerHouses.emplace_back(it.second);
+ }
+ }
+ return playerHouses;
+}
+
+std::shared_ptr Houses::getHouseByBidderName(std::string bidderName) {
+ for (const auto &it : houseMap) {
+ if (it.second->getBidderName() == bidderName) {
+ return it.second;
+ }
+ }
+ return nullptr;
+}
+
+uint16_t Houses::getHouseCountByAccount(uint32_t accountId) {
+ uint16_t count = 0;
+ for (const auto& it : houseMap) {
+ if (it.second->getOwnerAccountId() == accountId) {
+ ++count;
+ }
+ }
+ return count;
+}
+
bool Houses::loadHousesXML(const std::string &filename) {
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file(filename.c_str());
@@ -759,6 +832,13 @@ bool Houses::loadHousesXML(const std::string &filename) {
house->setRent(pugi::cast(houseNode.attribute("rent").value()));
house->setSize(pugi::cast(houseNode.attribute("size").value()));
house->setTownId(pugi::cast(houseNode.attribute("townid").value()));
+ house->setClientId(pugi::cast(houseNode.attribute("clientid").value()));
+
+ auto guildhallAttr = houseNode.attribute("guildhall");
+ if (!guildhallAttr.empty()) {
+ house->setGuildhall(static_cast(guildhallAttr.as_bool()));
+ }
+
auto maxBedsAttr = houseNode.attribute("beds");
int32_t maxBeds = -1;
if (!maxBedsAttr.empty()) {
@@ -767,6 +847,7 @@ bool Houses::loadHousesXML(const std::string &filename) {
house->setMaxBeds(maxBeds);
house->setOwner(0, false);
+ addHouseClientId(house->getClientId(), house);
}
return true;
}
diff --git a/src/map/house/house.hpp b/src/map/house/house.hpp
index aa4b746cc0a..c763e5de595 100644
--- a/src/map/house/house.hpp
+++ b/src/map/house/house.hpp
@@ -18,6 +18,8 @@ class House;
class BedItem;
class Player;
+using days = std::chrono::duration>;
+
class AccessList {
public:
void parseList(const std::string &list);
@@ -233,6 +235,77 @@ class House : public SharedObject {
bool hasNewOwnership() const;
void setNewOwnership();
+ void setClientId(uint32_t newClientId) {
+ this->clientId = newClientId;
+ }
+ uint32_t getClientId() const {
+ return clientId;
+ }
+
+ void setBidder(int32_t bidder) {
+ this->bidder = bidder;
+ }
+ int32_t getBidder() const {
+ return bidder;
+ }
+
+ void setBidderName(std::string bidderName) {
+ this->bidderName = bidderName;
+ }
+ std::string getBidderName() const {
+ return bidderName;
+ }
+
+ void setHighestBid(uint64_t bidValue) {
+ this->highestBid = bidValue;
+ }
+ uint64_t getHighestBid() const {
+ return highestBid;
+ }
+
+ void setInternalBid(uint64_t bidValue) {
+ this->internalBid = bidValue;
+ }
+ uint64_t getInternalBid() const {
+ return internalBid;
+ }
+
+ void setBidHolderLimit(uint64_t bidValue) {
+ this->bidHolderLimit = bidValue;
+ }
+ uint64_t getBidHolderLimit() const {
+ return bidHolderLimit;
+ }
+
+ void calculateBidEndDate(uint8_t daysToEnd);
+ void setBidEndDate(uint32_t bidEndDate) {
+ this->bidEndDate = bidEndDate;
+ };
+ uint32_t getBidEndDate() const {
+ return bidEndDate;
+ }
+
+ void setState(uint8_t state) {
+ this->state = state;
+ }
+ uint8_t getState() const {
+ return state;
+ }
+
+ void setOwnerAccountId(uint32_t accountId) {
+ this->ownerAccountId = accountId;
+ }
+ uint32_t getOwnerAccountId() const {
+ return ownerAccountId;
+ }
+
+ void setGuildhall(bool isGuildHall) {
+ this->guildHall = isGuildHall;
+ }
+ bool isGuildhall() const {
+ return guildHall;
+ }
+
private:
bool transferToDepot() const;
@@ -263,9 +336,20 @@ class House : public SharedObject {
uint32_t townId = 0;
uint32_t maxBeds = 4;
int32_t bedsCount = -1;
+ bool guildHall = false;
Position posEntry = {};
+ // House Auction
+ uint32_t clientId;
+ int32_t bidder = 0;
+ std::string bidderName = "";
+ uint64_t highestBid = 0;
+ uint64_t internalBid = 0;
+ uint64_t bidHolderLimit = 0;
+ uint32_t bidEndDate = 0;
+ uint8_t state = 0;
+
bool isLoaded = false;
void handleContainer(ItemList &moveItemList, std::shared_ptr
- item) const;
@@ -299,7 +383,26 @@ class Houses {
return it->second;
}
+ void addHouseClientId(uint32_t clientId, std::shared_ptr house) {
+ if (auto it = houseMapClientId.find(clientId); it != houseMapClientId.end()) {
+ return;
+ }
+
+ houseMapClientId.emplace(clientId, house);
+ }
+
+ std::shared_ptr getHouseByClientId(uint32_t clientId) {
+ auto it = houseMapClientId.find(clientId);
+ if (it == houseMapClientId.end()) {
+ return nullptr;
+ }
+ return it->second;
+ }
+
std::shared_ptr getHouseByPlayerId(uint32_t playerId);
+ std::vector> getAllHousesByPlayerId(uint32_t playerId);
+ std::shared_ptr getHouseByBidderName(std::string bidderName);
+ uint16_t getHouseCountByAccount(uint32_t accountId);
bool loadHousesXML(const std::string &filename);
@@ -311,4 +414,5 @@ class Houses {
private:
HouseMap houseMap;
+ HouseMap houseMapClientId;
};
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index ae67bad447f..6a0e8fe4cc1 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -1225,6 +1225,9 @@ void ProtocolGame::parsePacketFromDispatcher(NetworkMessage &msg, uint8_t recvby
case 0xAC:
parseChannelExclude(msg);
break;
+ case 0xAD:
+ parseCyclopediaHouseAuction(msg);
+ break;
case 0xAE:
parseSendBosstiary();
break;
@@ -6826,6 +6829,7 @@ void ProtocolGame::sendAddCreature(std::shared_ptr creature, const Pos
sendLootContainers();
sendBasicData();
+ sendHousesInfo();
// Wheel of destiny cooldown
if (!oldProtocol && g_configManager().getBoolean(TOGGLE_WHEELSYSTEM)) {
player->wheel()->sendGiftOfLifeCooldown();
@@ -9256,3 +9260,126 @@ void ProtocolGame::sendTakeScreenshot(Screenshot_t screenshotType) {
msg.addByte(screenshotType);
writeToOutputBuffer(msg);
}
+
+void ProtocolGame::parseCyclopediaHouseAuction(NetworkMessage& msg) {
+ if (oldProtocol) {
+ return;
+ }
+
+ uint8_t houseActionType = msg.getByte();
+ switch (houseActionType) {
+ case 0: {
+ const auto townName = msg.getString();
+ g_game().playerCyclopediaHousesByTown(player->getID(), townName);
+ break;
+ }
+ case 1: {
+ const uint32_t houseId = msg.get();
+ const uint64_t bidValue = msg.get();
+ g_game().playerCyclopediaHouseBid(player->getID(), houseId, bidValue);
+ break;
+ }
+ case 2: {
+ const uint32_t houseId = msg.get();
+ const uint32_t timestamp = msg.get();
+ g_game().playerCyclopediaHouseLeave(player->getID(), houseId, timestamp);
+ break;
+ }
+ case 3: {
+ break;
+ }
+ }
+}
+
+void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
+ NetworkMessage msg;
+ msg.addByte(0xC7);
+ msg.add(houses.size());
+ for (const auto& house : houses) {
+ const auto clientId = house.first;
+ const auto& houseData = house.second;
+
+ msg.add(clientId);
+ msg.addByte(0x01); // 0x00 = Renovation; 0x01 = Available
+
+ msg.addByte(houseData->getState());
+ if (houseData->getState() == 0) { // Available
+ bool bidder = houseData->getBidderName() == player->getName();
+ msg.addString(houseData->getBidderName());
+ msg.addByte(bidder ? 1 : 0);
+ uint8_t disableIndex = enumToValue(player->canBidHouse(clientId));
+ msg.addByte(disableIndex);
+
+ if (!houseData->getBidderName().empty()) {
+ msg.add(houseData->getBidEndDate());
+ msg.add(houseData->getHighestBid());
+ if (bidder) {
+ msg.add(houseData->getBidHolderLimit());
+ }
+ }
+ } else if (houseData->getState() == 2) { // Rented
+ auto ownerName = IOLoginData::getNameByGuid(houseData->getOwner());
+ msg.addString(ownerName);
+ msg.add(houseData->getPaidUntil());
+
+ bool rented = ownerName.compare(player->getName()) == 0;
+ msg.addByte(rented);
+ if (rented) {
+ msg.addByte(0);
+ msg.addByte(0);
+ }
+ }
+ }
+
+ writeToOutputBuffer(msg);
+}
+
+void ProtocolGame::sendHouseAuctionMessage(uint32_t houseId, HouseAuctionType type, uint8_t index, bool bidSuccess /* = false*/) {
+ NetworkMessage msg;
+ const auto typeValue = enumToValue(type);
+
+ msg.addByte(0xC3);
+ msg.add(houseId);
+ msg.addByte(typeValue);
+ if (bidSuccess && typeValue == 1) {
+ msg.addByte(0x00);
+ }
+ msg.addByte(index);
+
+ writeToOutputBuffer(msg);
+}
+
+void ProtocolGame::sendHousesInfo() {
+ NetworkMessage msg;
+
+ uint32_t houseClientId = 0;
+ const auto accountHouseCount = g_game().map.houses.getHouseCountByAccount(player->getAccountId());
+ const auto house = g_game().map.houses.getHouseByPlayerId(player->getGUID());
+ if (house) {
+ houseClientId = house->getClientId();
+ }
+
+ msg.addByte(0xC6);
+ msg.add(houseClientId);
+ msg.addByte(0x00);
+
+ msg.addByte(accountHouseCount); // Houses Account
+
+ msg.addByte(0x00);
+
+ msg.addByte(3);
+ msg.addByte(3);
+
+ msg.addByte(0x01);
+
+ msg.addByte(0x01);
+ msg.add(houseClientId);
+
+ const auto& housesList = g_game().map.houses.getHouses();
+ msg.add(housesList.size());
+ for (const auto& it : housesList) {
+ msg.add(it.second->getClientId());
+ }
+
+ writeToOutputBuffer(msg);
+}
\ No newline at end of file
diff --git a/src/server/network/protocol/protocolgame.hpp b/src/server/network/protocol/protocolgame.hpp
index fc27cd3abfc..d33708232ab 100644
--- a/src/server/network/protocol/protocolgame.hpp
+++ b/src/server/network/protocol/protocolgame.hpp
@@ -330,6 +330,11 @@ class ProtocolGame final : public Protocol {
void sendCyclopediaCharacterBadges();
void sendCyclopediaCharacterTitles();
+ void sendHousesInfo();
+ void parseCyclopediaHouseAuction(NetworkMessage& msg);
+ void sendCyclopediaHouseList(HouseMap houses);
+ void sendHouseAuctionMessage(uint32_t houseId, HouseAuctionType type, uint8_t index, bool bidSuccess);
+
void sendCreatureWalkthrough(std::shared_ptr creature, bool walkthrough);
void sendCreatureShield(std::shared_ptr creature);
void sendCreatureEmblem(std::shared_ptr creature);
From f16662f077fcc376299eaf89b010e1964e7b8648 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Sun, 27 Oct 2024 03:27:43 +0000
Subject: [PATCH 02/28] Code format - (Clang-format)
---
src/creatures/players/player.cpp | 4 ++--
src/enums/player_cyclopedia.hpp | 2 +-
src/game/game.cpp | 14 ++++++------
src/io/iomapserialize.cpp | 17 +-------------
src/map/house/house.cpp | 24 ++++++++++----------
src/server/network/protocol/protocolgame.cpp | 12 +++++-----
src/server/network/protocol/protocolgame.hpp | 2 +-
7 files changed, 30 insertions(+), 45 deletions(-)
diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp
index 4487523f395..d6ee3f5ad5f 100644
--- a/src/creatures/players/player.cpp
+++ b/src/creatures/players/player.cpp
@@ -8256,7 +8256,7 @@ BidErrorMessage Player::canBidHouse(uint32_t houseId) {
}
if (house->isGuildhall()) {
- if (getGuildRank() && getGuildRank()->level != 3) {
+ if (getGuildRank() && getGuildRank()->level != 3) {
return BidErrorMessage::Guildhall;
}
@@ -8266,4 +8266,4 @@ BidErrorMessage Player::canBidHouse(uint32_t houseId) {
}
return BidErrorMessage::NoError;
-}
\ No newline at end of file
+}
diff --git a/src/enums/player_cyclopedia.hpp b/src/enums/player_cyclopedia.hpp
index fb2a97dac13..3f1aef3f0c1 100644
--- a/src/enums/player_cyclopedia.hpp
+++ b/src/enums/player_cyclopedia.hpp
@@ -80,4 +80,4 @@ enum class BidErrorMessage : uint8_t {
NotEnoughMoney = 17,
NotEnoughGuildMoney = 21,
Internal = 24,
-};
\ No newline at end of file
+};
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 18281b3bc51..612aae6c297 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10242,7 +10242,7 @@ bool Game::removeFiendishMonster(uint32_t id, bool create /* = true*/) {
void Game::updateForgeableMonsters() {
if (auto influencedLimit = g_configManager().getNumber(FORGE_INFLUENCED_CREATURES_LIMIT, __FUNCTION__);
- forgeableMonsters.size() < influencedLimit * 2) {
+ forgeableMonsters.size() < influencedLimit * 2) {
forgeableMonsters.clear();
for (const auto &[monsterId, monster] : monsters) {
auto monsterTile = monster->getTile();
@@ -10748,10 +10748,10 @@ void Game::playerCyclopediaHousesByTown(uint32_t playerId, const std::string tow
HouseMap houses;
if (!townName.empty()) {
- const auto& housesList = g_game().map.houses.getHouses();
- for (const auto& it : housesList) {
- const auto& house = it.second;
- const auto& town = g_game().map.towns.getTown(house->getTownId());
+ const auto &housesList = g_game().map.houses.getHouses();
+ for (const auto &it : housesList) {
+ const auto &house = it.second;
+ const auto &town = g_game().map.towns.getTown(house->getTownId());
if (!town) {
return;
}
@@ -10802,7 +10802,7 @@ void Game::playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_
ret = BidErrorMessage::NotEnoughMoney;
auto retSuccess = BidSuccessMessage::BidSuccess;
- if(house->getBidderName().empty()) {
+ if (house->getBidderName().empty()) {
if (!processBankAuction(player, house, bidValue)) {
player->sendHouseAuctionMessage(houseId, HouseAuctionType::Bid, enumToValue(ret));
return;
@@ -10835,7 +10835,7 @@ void Game::playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_
house->setBidder(player->getGUID());
}
- const auto& town = g_game().map.towns.getTown(house->getTownId());
+ const auto &town = g_game().map.towns.getTown(house->getTownId());
if (!town) {
return;
}
diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp
index 41087ed202a..f45048482fd 100644
--- a/src/io/iomapserialize.cpp
+++ b/src/io/iomapserialize.cpp
@@ -363,22 +363,7 @@ bool IOMapSerialize::SaveHouseInfoGuard() {
houseUpdate.upsert({ "owner", "paid", "warnings", "name", "town_id", "rent", "size", "beds", "bidder", "bidder_name", "highest_bid", "internal_bid", "bid_end_date", "state" });
for (const auto &[key, house] : g_game().map.houses.getHouses()) {
- std::string values = fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}",
- house->getId(),
- house->getOwner(),
- house->getPaidUntil(),
- house->getPayRentWarnings(),
- db.escapeString(house->getName()),
- house->getTownId(), house->getRent(),
- house->getSize(),
- house->getBedCount(),
- house->getBidder(),
- db.escapeString(house->getBidderName()),
- house->getHighestBid(),
- house->getInternalBid(),
- house->getBidEndDate(),
- house->getState()
- );
+ std::string values = fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}", house->getId(), house->getOwner(), house->getPaidUntil(), house->getPayRentWarnings(), db.escapeString(house->getName()), house->getTownId(), house->getRent(), house->getSize(), house->getBedCount(), house->getBidder(), db.escapeString(house->getBidderName()), house->getHighestBid(), house->getInternalBid(), house->getBidEndDate(), house->getState());
if (!houseUpdate.addRow(values)) {
return false;
diff --git a/src/map/house/house.cpp b/src/map/house/house.cpp
index c7530187df1..f9cfe5f995c 100644
--- a/src/map/house/house.cpp
+++ b/src/map/house/house.cpp
@@ -482,11 +482,11 @@ void House::resetTransferItem() {
}
void House::calculateBidEndDate(uint8_t daysToEnd) {
- auto currentTimeMs = std::chrono::system_clock::now().time_since_epoch();
-
- std::chrono::system_clock::time_point now = std::chrono::system_clock::time_point(
- std::chrono::duration_cast(currentTimeMs)
- );
+ auto currentTimeMs = std::chrono::system_clock::now().time_since_epoch();
+
+ std::chrono::system_clock::time_point now = std::chrono::system_clock::time_point(
+ std::chrono::duration_cast(currentTimeMs)
+ );
// Truncate to whole days since epoch
days daysSinceEpoch = std::chrono::duration_cast(now.time_since_epoch());
@@ -784,13 +784,13 @@ std::shared_ptr Houses::getHouseByBidderName(std::string bidderName) {
}
uint16_t Houses::getHouseCountByAccount(uint32_t accountId) {
- uint16_t count = 0;
- for (const auto& it : houseMap) {
- if (it.second->getOwnerAccountId() == accountId) {
- ++count;
- }
- }
- return count;
+ uint16_t count = 0;
+ for (const auto &it : houseMap) {
+ if (it.second->getOwnerAccountId() == accountId) {
+ ++count;
+ }
+ }
+ return count;
}
bool Houses::loadHousesXML(const std::string &filename) {
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index 6a0e8fe4cc1..2fa8a4b3a4b 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -9261,7 +9261,7 @@ void ProtocolGame::sendTakeScreenshot(Screenshot_t screenshotType) {
writeToOutputBuffer(msg);
}
-void ProtocolGame::parseCyclopediaHouseAuction(NetworkMessage& msg) {
+void ProtocolGame::parseCyclopediaHouseAuction(NetworkMessage &msg) {
if (oldProtocol) {
return;
}
@@ -9295,9 +9295,9 @@ void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
NetworkMessage msg;
msg.addByte(0xC7);
msg.add(houses.size());
- for (const auto& house : houses) {
+ for (const auto &house : houses) {
const auto clientId = house.first;
- const auto& houseData = house.second;
+ const auto &houseData = house.second;
msg.add(clientId);
msg.addByte(0x01); // 0x00 = Renovation; 0x01 = Available
@@ -9375,11 +9375,11 @@ void ProtocolGame::sendHousesInfo() {
msg.addByte(0x01);
msg.add(houseClientId);
- const auto& housesList = g_game().map.houses.getHouses();
+ const auto &housesList = g_game().map.houses.getHouses();
msg.add(housesList.size());
- for (const auto& it : housesList) {
+ for (const auto &it : housesList) {
msg.add(it.second->getClientId());
}
writeToOutputBuffer(msg);
-}
\ No newline at end of file
+}
diff --git a/src/server/network/protocol/protocolgame.hpp b/src/server/network/protocol/protocolgame.hpp
index d33708232ab..8a272c8ea8c 100644
--- a/src/server/network/protocol/protocolgame.hpp
+++ b/src/server/network/protocol/protocolgame.hpp
@@ -331,7 +331,7 @@ class ProtocolGame final : public Protocol {
void sendCyclopediaCharacterTitles();
void sendHousesInfo();
- void parseCyclopediaHouseAuction(NetworkMessage& msg);
+ void parseCyclopediaHouseAuction(NetworkMessage &msg);
void sendCyclopediaHouseList(HouseMap houses);
void sendHouseAuctionMessage(uint32_t houseId, HouseAuctionType type, uint8_t index, bool bidSuccess);
From 8b3e60f848bab14aea39b577eed22e33fabe538e Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Sun, 27 Oct 2024 02:12:15 -0300
Subject: [PATCH 03/28] sonar issues
---
src/creatures/players/player.hpp | 2 +-
src/game/game.cpp | 10 ++--
src/game/game.hpp | 2 +-
src/map/house/house.cpp | 38 +++++++-------
src/map/house/house.hpp | 52 ++++++++++----------
src/server/network/protocol/protocolgame.cpp | 5 +-
6 files changed, 53 insertions(+), 56 deletions(-)
diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp
index dedf6b9d119..b3fb4ed79d9 100644
--- a/src/creatures/players/player.hpp
+++ b/src/creatures/players/player.hpp
@@ -1584,7 +1584,7 @@ class Player final : public Creature, public Cylinder, public Bankable {
}
BidErrorMessage canBidHouse(uint32_t houseId);
- void sendCyclopediaHouseList(HouseMap houses) {
+ void sendCyclopediaHouseList(const HouseMap &houses) {
if (client) {
client->sendCyclopediaHouseList(houses);
}
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 612aae6c297..f1e58285a20 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10241,7 +10241,7 @@ bool Game::removeFiendishMonster(uint32_t id, bool create /* = true*/) {
}
void Game::updateForgeableMonsters() {
- if (auto influencedLimit = g_configManager().getNumber(FORGE_INFLUENCED_CREATURES_LIMIT, __FUNCTION__);
+ if (auto influencedLimit = g_configManager().getNumber(FORGE_INFLUENCED_CREATURES_LIMIT);
forgeableMonsters.size() < influencedLimit * 2) {
forgeableMonsters.clear();
for (const auto &[monsterId, monster] : monsters) {
@@ -10740,7 +10740,7 @@ const std::unordered_map &Game::getHirelingOutfits() {
return m_hirelingOutfits;
}
-void Game::playerCyclopediaHousesByTown(uint32_t playerId, const std::string townName) {
+void Game::playerCyclopediaHousesByTown(uint32_t playerId, const std::string &townName) {
std::shared_ptr player = getPlayerByID(playerId);
if (!player) {
return;
@@ -10756,7 +10756,7 @@ void Game::playerCyclopediaHousesByTown(uint32_t playerId, const std::string tow
return;
}
- const std::string houseTown = town->getName();
+ const std::string &houseTown = town->getName();
if (houseTown == townName) {
houses.emplace(house->getClientId(), house);
}
@@ -10781,7 +10781,7 @@ void Game::playerCyclopediaHousesByTown(uint32_t playerId, const std::string tow
}
void Game::playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_t bidValue) {
- if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION, __FUNCTION__)) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
return;
}
@@ -10846,7 +10846,7 @@ void Game::playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_
}
void Game::playerCyclopediaHouseLeave(uint32_t playerId, uint32_t houseId, uint32_t timestamp) {
- if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION, __FUNCTION__)) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
return;
}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index 1b0b9b369d3..5258d0f1fc6 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -316,7 +316,7 @@ class Game {
static std::string getSkillNameById(uint8_t &skill);
// House Auction
- void playerCyclopediaHousesByTown(uint32_t playerId, const std::string townName);
+ void playerCyclopediaHousesByTown(uint32_t playerId, const std::string &townName);
void playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_t bidValue);
void playerCyclopediaHouseLeave(uint32_t playerId, uint32_t houseId, uint32_t timestamp);
bool processBankAuction(std::shared_ptr player, std::shared_ptr house, uint64_t bid, bool replace = false);
diff --git a/src/map/house/house.cpp b/src/map/house/house.cpp
index f9cfe5f995c..9a140ee9b65 100644
--- a/src/map/house/house.cpp
+++ b/src/map/house/house.cpp
@@ -105,7 +105,7 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, std::shared
}
if (guid != 0) {
- std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD, __FUNCTION__));
+ std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD));
time_t currentTime = time(nullptr);
if (strRentPeriod == "yearly") {
currentTime += 24 * 60 * 60 * 365;
@@ -140,7 +140,7 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, std::shared
owner = guid;
ownerName = name;
ownerAccountId = result->getNumber("account_id");
- state = 2;
+ m_state = 2;
}
}
@@ -155,14 +155,14 @@ void House::updateDoorDescription() const {
ss << "It belongs to house '" << houseName << "'. Nobody owns this house.";
}
- if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION, __FUNCTION__)) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
ss << " It is " << getSize() << " square meters.";
const int32_t housePrice = getPrice();
if (housePrice != -1) {
- if (g_configManager().getBoolean(HOUSE_PURSHASED_SHOW_PRICE, __FUNCTION__) || owner == 0) {
+ if (g_configManager().getBoolean(HOUSE_PURSHASED_SHOW_PRICE) || owner == 0) {
ss << " It costs " << formatNumber(getPrice()) << " gold coins.";
}
- std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD, __FUNCTION__));
+ std::string strRentPeriod = asLowerCaseString(g_configManager().getString(HOUSE_RENT_PERIOD));
if (strRentPeriod != "never") {
ss << " The rent cost is " << formatNumber(getRent()) << " gold coins and it is billed " << strRentPeriod << ".";
}
@@ -484,7 +484,7 @@ void House::resetTransferItem() {
void House::calculateBidEndDate(uint8_t daysToEnd) {
auto currentTimeMs = std::chrono::system_clock::now().time_since_epoch();
- std::chrono::system_clock::time_point now = std::chrono::system_clock::time_point(
+ auto now = std::chrono::system_clock::time_point(
std::chrono::duration_cast(currentTimeMs)
);
@@ -492,11 +492,11 @@ void House::calculateBidEndDate(uint8_t daysToEnd) {
days daysSinceEpoch = std::chrono::duration_cast(now.time_since_epoch());
// Get today's date at 00:00:00 UTC
- std::chrono::system_clock::time_point todayMidnight = std::chrono::system_clock::time_point(daysSinceEpoch);
+ auto todayMidnight = std::chrono::system_clock::time_point(daysSinceEpoch);
std::chrono::system_clock::time_point targetDay = todayMidnight + days(daysToEnd);
- const auto serverSaveTime = g_configManager().getString(GLOBAL_SERVER_SAVE_TIME, __FUNCTION__);
+ const auto serverSaveTime = g_configManager().getString(GLOBAL_SERVER_SAVE_TIME);
std::vector params = vectorAtoi(explodeString(serverSaveTime, ":"));
int32_t hour = params.front();
@@ -513,9 +513,9 @@ void House::calculateBidEndDate(uint8_t daysToEnd) {
std::time_t resultTime = std::chrono::system_clock::to_time_t(targetTime);
std::tm* localTime = std::localtime(&resultTime);
- uint32_t bidEndDate = static_cast(std::mktime(localTime));
+ auto bidEndDate = static_cast(std::mktime(localTime));
- this->bidEndDate = bidEndDate;
+ this->m_bidEndDate = bidEndDate;
}
std::shared_ptr HouseTransferItem::createHouseTransferItem(std::shared_ptr house) {
@@ -766,18 +766,18 @@ std::shared_ptr Houses::getHouseByPlayerId(uint32_t playerId) {
std::vector> Houses::getAllHousesByPlayerId(uint32_t playerId) {
std::vector> playerHouses;
- for (const auto &it : houseMap) {
- if (it.second->getOwner() == playerId) {
- playerHouses.emplace_back(it.second);
+ for (const auto &[id, house] : houseMap) {
+ if (house->getOwner() == playerId) {
+ playerHouses.emplace_back(house);
}
}
return playerHouses;
}
-std::shared_ptr Houses::getHouseByBidderName(std::string bidderName) {
- for (const auto &it : houseMap) {
- if (it.second->getBidderName() == bidderName) {
- return it.second;
+std::shared_ptr Houses::getHouseByBidderName(const std::string &bidderName) {
+ for (const auto &[id, house] : houseMap) {
+ if (house->getBidderName() == bidderName) {
+ return house;
}
}
return nullptr;
@@ -785,8 +785,8 @@ std::shared_ptr Houses::getHouseByBidderName(std::string bidderName) {
uint16_t Houses::getHouseCountByAccount(uint32_t accountId) {
uint16_t count = 0;
- for (const auto &it : houseMap) {
- if (it.second->getOwnerAccountId() == accountId) {
+ for (const auto &[id, house] : houseMap) {
+ if (house->getOwnerAccountId() == accountId) {
++count;
}
}
diff --git a/src/map/house/house.hpp b/src/map/house/house.hpp
index c763e5de595..8aefbf7002b 100644
--- a/src/map/house/house.hpp
+++ b/src/map/house/house.hpp
@@ -236,60 +236,60 @@ class House : public SharedObject {
void setNewOwnership();
void setClientId(uint32_t newClientId) {
- this->clientId = newClientId;
+ this->m_clientId = newClientId;
}
uint32_t getClientId() const {
- return clientId;
+ return m_clientId;
}
void setBidder(int32_t bidder) {
- this->bidder = bidder;
+ this->m_bidder = bidder;
}
int32_t getBidder() const {
- return bidder;
+ return m_bidder;
}
- void setBidderName(std::string bidderName) {
- this->bidderName = bidderName;
+ void setBidderName(const std::string &bidderName) {
+ this->m_bidderName = bidderName;
}
std::string getBidderName() const {
- return bidderName;
+ return m_bidderName;
}
void setHighestBid(uint64_t bidValue) {
- this->highestBid = bidValue;
+ this->m_highestBid = bidValue;
}
uint64_t getHighestBid() const {
- return highestBid;
+ return m_highestBid;
}
void setInternalBid(uint64_t bidValue) {
- this->internalBid = bidValue;
+ this->m_internalBid = bidValue;
}
uint64_t getInternalBid() const {
- return internalBid;
+ return m_internalBid;
}
void setBidHolderLimit(uint64_t bidValue) {
- this->bidHolderLimit = bidValue;
+ this->m_bidHolderLimit = bidValue;
}
uint64_t getBidHolderLimit() const {
- return bidHolderLimit;
+ return m_bidHolderLimit;
}
void calculateBidEndDate(uint8_t daysToEnd);
void setBidEndDate(uint32_t bidEndDate) {
- this->bidEndDate = bidEndDate;
+ this->m_bidEndDate = bidEndDate;
};
uint32_t getBidEndDate() const {
- return bidEndDate;
+ return m_bidEndDate;
}
void setState(uint8_t state) {
- this->state = state;
+ this->m_state = state;
}
uint8_t getState() const {
- return state;
+ return m_state;
}
void setOwnerAccountId(uint32_t accountId) {
@@ -341,14 +341,14 @@ class House : public SharedObject {
Position posEntry = {};
// House Auction
- uint32_t clientId;
- int32_t bidder = 0;
- std::string bidderName = "";
- uint64_t highestBid = 0;
- uint64_t internalBid = 0;
- uint64_t bidHolderLimit = 0;
- uint32_t bidEndDate = 0;
- uint8_t state = 0;
+ uint32_t m_clientId;
+ int32_t m_bidder = 0;
+ std::string m_bidderName = "";
+ uint64_t m_highestBid = 0;
+ uint64_t m_internalBid = 0;
+ uint64_t m_bidHolderLimit = 0;
+ uint32_t m_bidEndDate = 0;
+ uint8_t m_state = 0;
bool isLoaded = false;
@@ -401,7 +401,7 @@ class Houses {
std::shared_ptr getHouseByPlayerId(uint32_t playerId);
std::vector> getAllHousesByPlayerId(uint32_t playerId);
- std::shared_ptr getHouseByBidderName(std::string bidderName);
+ std::shared_ptr getHouseByBidderName(const std::string &bidderName);
uint16_t getHouseCountByAccount(uint32_t accountId);
bool loadHousesXML(const std::string &filename);
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index 2fa8a4b3a4b..2be8e4148cf 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -9295,10 +9295,7 @@ void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
NetworkMessage msg;
msg.addByte(0xC7);
msg.add(houses.size());
- for (const auto &house : houses) {
- const auto clientId = house.first;
- const auto &houseData = house.second;
-
+ for (const auto &[clientId, houseData] : houses) {
msg.add(clientId);
msg.addByte(0x01); // 0x00 = Renovation; 0x01 = Available
From bf2260295641a1f4592b8ba2210d869bc2200f35 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Mon, 28 Oct 2024 00:27:18 -0300
Subject: [PATCH 04/28] revert
---
src/game/game.cpp | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/src/game/game.cpp b/src/game/game.cpp
index f1e58285a20..c45d9efa513 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10241,18 +10241,15 @@ bool Game::removeFiendishMonster(uint32_t id, bool create /* = true*/) {
}
void Game::updateForgeableMonsters() {
- if (auto influencedLimit = g_configManager().getNumber(FORGE_INFLUENCED_CREATURES_LIMIT);
- forgeableMonsters.size() < influencedLimit * 2) {
- forgeableMonsters.clear();
- for (const auto &[monsterId, monster] : monsters) {
- auto monsterTile = monster->getTile();
- if (!monsterTile) {
- continue;
- }
+ forgeableMonsters.clear();
+ for (const auto &[monsterId, monster] : monsters) {
+ auto monsterTile = monster->getTile();
+ if (!monsterTile) {
+ continue;
+ }
- if (monster->canBeForgeMonster() && !monsterTile->hasFlag(TILESTATE_NOLOGOUT)) {
- forgeableMonsters.push_back(monster->getID());
- }
+ if (monster->canBeForgeMonster() && !monsterTile->hasFlag(TILESTATE_NOLOGOUT)) {
+ forgeableMonsters.push_back(monster->getID());
}
}
From 75fc10d197f9a4a6a65e5a5e4bf48b406d4f7bd8 Mon Sep 17 00:00:00 2001
From: Pedro Henrique Alves Cruz
Date: Tue, 29 Oct 2024 19:16:39 -0300
Subject: [PATCH 05/28] fix: load state into house object
---
src/io/iomapserialize.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp
index 1e5bed79d78..8313e2c26ac 100644
--- a/src/io/iomapserialize.cpp
+++ b/src/io/iomapserialize.cpp
@@ -326,6 +326,7 @@ bool IOMapSerialize::loadHouseInfo() {
house->setInternalBid(internalBid);
house->setBidHolderLimit(internalBid);
house->setBidEndDate(bidEndDate);
+ house->setState(state);
}
} while (result->next());
From f6a76ff555be1682daa122555633ec7f0e8b157b Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Tue, 29 Oct 2024 22:15:14 -0300
Subject: [PATCH 06/28] feat: show move out info
---
src/game/game.cpp | 25 +++++++++++++++++++-
src/game/game.hpp | 3 ++-
src/server/network/protocol/protocolgame.cpp | 23 +++++++++++++++++-
3 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 4603e36a0dc..6f39e567cdd 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10842,7 +10842,7 @@ void Game::playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_
playerCyclopediaHousesByTown(playerId, houseTown);
}
-void Game::playerCyclopediaHouseLeave(uint32_t playerId, uint32_t houseId, uint32_t timestamp) {
+void Game::playerCyclopediaHouseMoveOut(uint32_t playerId, uint32_t houseId, uint32_t timestamp) {
if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
return;
}
@@ -10859,6 +10859,29 @@ void Game::playerCyclopediaHouseLeave(uint32_t playerId, uint32_t houseId, uint3
house->setBidEndDate(timestamp);
house->setBidder(-1);
+ house->setState(4);
+
+ playerCyclopediaHousesByTown(playerId, "");
+}
+
+void Game::playerCyclopediaHouseCancelMoveOut(uint32_t playerId, uint32_t houseId) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
+ return;
+ }
+
+ std::shared_ptr player = getPlayerByID(playerId);
+ if (!player) {
+ return;
+ }
+
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house || house->getOwner() != player->getGUID()) {
+ return;
+ }
+
+ house->setBidEndDate(0);
+ house->setBidder(0);
+ house->setState(2);
playerCyclopediaHousesByTown(playerId, "");
}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index 5258d0f1fc6..82eecf53812 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -318,7 +318,8 @@ class Game {
// House Auction
void playerCyclopediaHousesByTown(uint32_t playerId, const std::string &townName);
void playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_t bidValue);
- void playerCyclopediaHouseLeave(uint32_t playerId, uint32_t houseId, uint32_t timestamp);
+ void playerCyclopediaHouseMoveOut(uint32_t playerId, uint32_t houseId, uint32_t timestamp);
+ void playerCyclopediaHouseCancelMoveOut(uint32_t playerId, uint32_t houseId);
bool processBankAuction(std::shared_ptr player, std::shared_ptr house, uint64_t bid, bool replace = false);
void updatePlayerSaleItems(uint32_t playerId);
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index 2be8e4148cf..0c82f145fd8 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -9267,6 +9267,7 @@ void ProtocolGame::parseCyclopediaHouseAuction(NetworkMessage &msg) {
}
uint8_t houseActionType = msg.getByte();
+ g_logger().warn("houseActionType {}", houseActionType);
switch (houseActionType) {
case 0: {
const auto townName = msg.getString();
@@ -9282,12 +9283,17 @@ void ProtocolGame::parseCyclopediaHouseAuction(NetworkMessage &msg) {
case 2: {
const uint32_t houseId = msg.get();
const uint32_t timestamp = msg.get();
- g_game().playerCyclopediaHouseLeave(player->getID(), houseId, timestamp);
+ g_game().playerCyclopediaHouseMoveOut(player->getID(), houseId, timestamp);
break;
}
case 3: {
break;
}
+ case 4: {
+ const uint32_t houseId = msg.get();
+ g_game().playerCyclopediaHouseCancelMoveOut(player->getID(), houseId);
+ break;
+ }
}
}
@@ -9325,6 +9331,21 @@ void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
msg.addByte(0);
msg.addByte(0);
}
+ } else if (houseData->getState() == 4) { // Move Out
+ auto ownerName = IOLoginData::getNameByGuid(houseData->getOwner());
+ msg.addString(ownerName);
+ msg.add(houseData->getPaidUntil());
+
+ bool isOwner = ownerName.compare(player->getName()) == 0;
+ msg.addByte(isOwner);
+ if (isOwner) {
+ msg.addByte(0); // ?
+ msg.addByte(0); // ?
+ msg.add(houseData->getBidEndDate());
+ msg.addByte(0);
+ } else {
+ msg.add(houseData->getBidEndDate());
+ }
}
}
From d27a2462def12a48c24fecd5f2f1003b4f99eb24 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Tue, 29 Oct 2024 23:53:07 -0300
Subject: [PATCH 07/28] fix days to end bid
---
src/game/game.cpp | 2 +-
src/server/network/protocol/protocolgame.cpp | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 6f39e567cdd..b49130a3407 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10809,7 +10809,7 @@ void Game::playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_
house->setBidHolderLimit(bidValue);
house->setBidderName(player->getName());
house->setBidder(player->getGUID());
- house->calculateBidEndDate(1);
+ house->calculateBidEndDate(7);
} else if (house->getBidderName() == player->getName()) {
if (!processBankAuction(player, house, bidValue, true)) {
player->sendHouseAuctionMessage(houseId, HouseAuctionType::Bid, enumToValue(ret));
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index 0c82f145fd8..a4031e097d0 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -9267,7 +9267,6 @@ void ProtocolGame::parseCyclopediaHouseAuction(NetworkMessage &msg) {
}
uint8_t houseActionType = msg.getByte();
- g_logger().warn("houseActionType {}", houseActionType);
switch (houseActionType) {
case 0: {
const auto townName = msg.getString();
From 6a35471b46602000480d78e87b337b922ea91ed0 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 02:36:36 -0300
Subject: [PATCH 08/28] fix load house logic
---
src/game/game.cpp | 8 +++-----
src/game/game.hpp | 2 +-
src/io/iomapserialize.cpp | 11 +++++------
3 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/src/game/game.cpp b/src/game/game.cpp
index eaaffb05059..915128d6388 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10904,12 +10904,11 @@ void Game::playerCyclopediaHouseMoveOut(uint32_t playerId, uint32_t houseId, uin
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getOwner() != player->getGUID()) {
+ if (!house || house->getOwner() != player->getGUID() || house->getState() != 2) {
return;
}
house->setBidEndDate(timestamp);
- house->setBidder(-1);
house->setState(4);
playerCyclopediaHousesByTown(playerId, "");
@@ -10926,18 +10925,17 @@ void Game::playerCyclopediaHouseCancelMoveOut(uint32_t playerId, uint32_t houseI
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getOwner() != player->getGUID()) {
+ if (!house || house->getOwner() != player->getGUID() || house->getState() != 4) {
return;
}
house->setBidEndDate(0);
- house->setBidder(0);
house->setState(2);
playerCyclopediaHousesByTown(playerId, "");
}
-bool Game::processBankAuction(std::shared_ptr player, std::shared_ptr house, uint64_t bid, bool replace /* = false*/) {
+bool Game::processBankAuction(std::shared_ptr player, const std::shared_ptr &house, uint64_t bid, bool replace /* = false*/) {
if (!replace && player->getBankBalance() < (house->getRent() + bid)) {
return false;
}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index 99790ce2f67..a631619f7ae 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -320,7 +320,7 @@ class Game {
void playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_t bidValue);
void playerCyclopediaHouseMoveOut(uint32_t playerId, uint32_t houseId, uint32_t timestamp);
void playerCyclopediaHouseCancelMoveOut(uint32_t playerId, uint32_t houseId);
- bool processBankAuction(std::shared_ptr player, std::shared_ptr house, uint64_t bid, bool replace = false);
+ bool processBankAuction(std::shared_ptr player, const std::shared_ptr &house, uint64_t bid, bool replace = false);
void updatePlayerSaleItems(uint32_t playerId);
diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp
index ef6fb1beee4..562aa02a0d7 100644
--- a/src/io/iomapserialize.cpp
+++ b/src/io/iomapserialize.cpp
@@ -300,25 +300,25 @@ bool IOMapSerialize::loadHouseInfo() {
g_logger().debug("Setting house id '{}' owner to player GUID '{}'", houseId, newOwner);
house->setOwner(newOwner);
}
- } else if (state == 0 && bidder > 0 && timeNow > bidEndDate) {
+ } else if (state == 0 && timeNow > bidEndDate && bidder > 0) { // Available
+ g_logger().debug("[BID] - Setting house id '{}' owner to player GUID '{}'", houseId, bidder);
if (highestBid < internalBid) {
uint32_t diff = internalBid - highestBid;
IOLoginData::increaseBankBalance(bidder, diff);
}
- g_logger().debug("Setting house id '{}' owner to player GUID '{}'", houseId, bidder);
house->setOwner(bidder);
bidder = 0;
bidderName = "";
highestBid = 0;
internalBid = 0;
bidEndDate = 0;
- } else if (state == 2 && bidder == -1 && timeNow > bidEndDate) {
- g_logger().debug("Removing house id '{}' owner", houseId);
+ } else if (state == 4 && timeNow > bidEndDate) { // Move Out
+ g_logger().debug("[MOVE OUT] - Removing house id '{}' owner", houseId);
house->setOwner(0);
bidEndDate = 0;
- bidder = 0;
} else {
house->setOwner(owner, false);
+ house->setState(state);
}
house->setBidder(bidder);
house->setBidderName(bidderName);
@@ -326,7 +326,6 @@ bool IOMapSerialize::loadHouseInfo() {
house->setInternalBid(internalBid);
house->setBidHolderLimit(internalBid);
house->setBidEndDate(bidEndDate);
- house->setState(state);
}
} while (result->next());
From e057cd046a5e799489b9759f5034c9e7f8adc95c Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 14:42:00 -0300
Subject: [PATCH 09/28] feat: transfer
---
data-otservbr-global/migrations/46.lua | 1 +
src/enums/player_cyclopedia.hpp | 7 ++
src/game/game.cpp | 121 +++++++++++++++++--
src/game/game.hpp | 4 +
src/io/iomapserialize.cpp | 30 +++--
src/map/house/house.cpp | 4 +-
src/map/house/house.hpp | 15 ++-
src/server/network/protocol/protocolgame.cpp | 57 ++++++++-
8 files changed, 213 insertions(+), 26 deletions(-)
diff --git a/data-otservbr-global/migrations/46.lua b/data-otservbr-global/migrations/46.lua
index 600bb3785ad..d1709730493 100644
--- a/data-otservbr-global/migrations/46.lua
+++ b/data-otservbr-global/migrations/46.lua
@@ -17,6 +17,7 @@ function onUpdateDatabase()
ADD `internal_bid` int(11) NOT NULL DEFAULT '0',
ADD `bid_end_date` int(11) NOT NULL DEFAULT '0',
ADD `state` smallint(5) UNSIGNED NOT NULL DEFAULT '0'
+ ADD `transfer_status` tinyint(1) DEFAULT '0'
]])
db.query([[
diff --git a/src/enums/player_cyclopedia.hpp b/src/enums/player_cyclopedia.hpp
index 57c0c3d9176..3c515df8b66 100644
--- a/src/enums/player_cyclopedia.hpp
+++ b/src/enums/player_cyclopedia.hpp
@@ -61,6 +61,13 @@ enum class CyclopediaMapData_t : uint8_t {
SetCurrentArea = 10,
};
+enum class CyclopediaHouseState : uint8_t {
+ Available = 0,
+ Rented = 2,
+ Transfer = 3,
+ MoveOut = 4,
+};
+
enum class HouseAuctionType : uint8_t {
Bid = 1,
MoveOut = 2,
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 915128d6388..63a5dc4df98 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10818,11 +10818,11 @@ void Game::playerCyclopediaHousesByTown(uint32_t playerId, const std::string &to
}
houses.emplace(playerHouse->getClientId(), playerHouse);
}
- } else {
- const auto house = g_game().map.houses.getHouseByBidderName(player->getName());
- if (house) {
- houses.emplace(house->getClientId(), house);
- }
+ }
+
+ const auto house = g_game().map.houses.getHouseByBidderName(player->getName());
+ if (house) {
+ houses.emplace(house->getClientId(), house);
}
}
player->sendCyclopediaHouseList(houses);
@@ -10904,12 +10904,12 @@ void Game::playerCyclopediaHouseMoveOut(uint32_t playerId, uint32_t houseId, uin
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getOwner() != player->getGUID() || house->getState() != 2) {
+ if (!house || house->getOwner() != player->getGUID() || house->getState() != CyclopediaHouseState::Rented) {
return;
}
house->setBidEndDate(timestamp);
- house->setState(4);
+ house->setState(CyclopediaHouseState::MoveOut);
playerCyclopediaHousesByTown(playerId, "");
}
@@ -10925,12 +10925,115 @@ void Game::playerCyclopediaHouseCancelMoveOut(uint32_t playerId, uint32_t houseI
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getOwner() != player->getGUID() || house->getState() != 4) {
+ if (!house || house->getOwner() != player->getGUID() || house->getState() != CyclopediaHouseState::MoveOut) {
+ return;
+ }
+
+ house->setBidEndDate(0);
+ house->setState(CyclopediaHouseState::Rented);
+
+ playerCyclopediaHousesByTown(playerId, "");
+}
+
+void Game::playerCyclopediaHouseTransfer(uint32_t playerId, uint32_t houseId, uint32_t timestamp, const std::string &newOwnerName, uint64_t bidValue) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
+ return;
+ }
+
+ const std::shared_ptr &owner = getPlayerByID(playerId);
+ if (!owner) {
+ return;
+ }
+
+ const std::shared_ptr &newOwner = getPlayerByName(newOwnerName, true);
+ if (!newOwner) {
+ return;
+ }
+
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house || house->getOwner() != owner->getGUID() || house->getState() != CyclopediaHouseState::Rented) {
+ return;
+ }
+
+ house->setBidderName(newOwnerName);
+ house->setBidder(newOwner->getGUID());
+ house->setInternalBid(bidValue);
+ house->setBidEndDate(timestamp);
+ house->setState(CyclopediaHouseState::Transfer);
+
+ playerCyclopediaHousesByTown(playerId, "");
+}
+
+void Game::playerCyclopediaHouseCancelTransfer(uint32_t playerId, uint32_t houseId) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
+ return;
+ }
+
+ const std::shared_ptr &player = getPlayerByID(playerId);
+ if (!player) {
+ return;
+ }
+
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house || house->getOwner() != player->getGUID() || house->getState() != CyclopediaHouseState::Transfer) {
+ return;
+ }
+
+ house->setBidderName("");
+ house->setBidder(0);
+ house->setInternalBid(0);
+ house->setBidEndDate(0);
+ house->setState(CyclopediaHouseState::Rented);
+ house->setTransferStatus(false);
+
+ playerCyclopediaHousesByTown(playerId, "");
+}
+
+void Game::playerCyclopediaHouseAcceptTransfer(uint32_t playerId, uint32_t houseId) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
+ return;
+ }
+
+ const std::shared_ptr &player = getPlayerByID(playerId);
+ if (!player) {
+ return;
+ }
+
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house || house->getBidder() != player->getGUID() || house->getState() != CyclopediaHouseState::Transfer) {
+ return;
+ }
+
+ if (!processBankAuction(player, house, house->getInternalBid())) {
+ return;
+ }
+
+ house->setTransferStatus(true);
+
+ playerCyclopediaHousesByTown(playerId, "");
+}
+
+void Game::playerCyclopediaHouseRejectTransfer(uint32_t playerId, uint32_t houseId) {
+ if (!g_configManager().getBoolean(CYCLOPEDIA_HOUSE_AUCTION)) {
+ return;
+ }
+
+ const std::shared_ptr &player = getPlayerByID(playerId);
+ if (!player) {
+ return;
+ }
+
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house || house->getBidder() != player->getGUID() || house->getState() != CyclopediaHouseState::Transfer) {
return;
}
+ house->setBidderName("");
+ house->setBidder(0);
+ house->setInternalBid(0);
house->setBidEndDate(0);
- house->setState(2);
+ house->setState(CyclopediaHouseState::Rented);
+ house->setTransferStatus(false);
playerCyclopediaHousesByTown(playerId, "");
}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index a631619f7ae..dea774b295c 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -320,6 +320,10 @@ class Game {
void playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_t bidValue);
void playerCyclopediaHouseMoveOut(uint32_t playerId, uint32_t houseId, uint32_t timestamp);
void playerCyclopediaHouseCancelMoveOut(uint32_t playerId, uint32_t houseId);
+ void playerCyclopediaHouseTransfer(uint32_t playerId, uint32_t houseId, uint32_t timestamp, const std::string &newOwnerName, uint64_t bidValue);
+ void playerCyclopediaHouseCancelTransfer(uint32_t playerId, uint32_t houseId);
+ void playerCyclopediaHouseAcceptTransfer(uint32_t playerId, uint32_t houseId);
+ void playerCyclopediaHouseRejectTransfer(uint32_t playerId, uint32_t houseId);
bool processBankAuction(std::shared_ptr player, const std::shared_ptr &house, uint64_t bid, bool replace = false);
void updatePlayerSaleItems(uint32_t playerId);
diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp
index 562aa02a0d7..2e3c0c9d16a 100644
--- a/src/io/iomapserialize.cpp
+++ b/src/io/iomapserialize.cpp
@@ -271,7 +271,7 @@ void IOMapSerialize::saveTile(PropWriteStream &stream, const std::shared_ptrgetNumber("highest_bid");
uint32_t internalBid = result->getNumber("internal_bid");
uint32_t bidEndDate = result->getNumber("bid_end_date");
- uint32_t state = result->getNumber("state");
- const auto timeNow = OTSYS_TIME(true);
+ auto state = static_cast(result->getNumber("state"));
+ const auto timeNow = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count();
// Transfer house owner
auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART);
if (isTransferOnRestart && newOwner >= 0) {
@@ -300,7 +300,7 @@ bool IOMapSerialize::loadHouseInfo() {
g_logger().debug("Setting house id '{}' owner to player GUID '{}'", houseId, newOwner);
house->setOwner(newOwner);
}
- } else if (state == 0 && timeNow > bidEndDate && bidder > 0) { // Available
+ } else if (state == CyclopediaHouseState::Available && timeNow > bidEndDate && bidder > 0) {
g_logger().debug("[BID] - Setting house id '{}' owner to player GUID '{}'", houseId, bidder);
if (highestBid < internalBid) {
uint32_t diff = internalBid - highestBid;
@@ -312,7 +312,20 @@ bool IOMapSerialize::loadHouseInfo() {
highestBid = 0;
internalBid = 0;
bidEndDate = 0;
- } else if (state == 4 && timeNow > bidEndDate) { // Move Out
+ } else if (state == CyclopediaHouseState::Transfer && timeNow > bidEndDate && bidder > 0) {
+ g_logger().debug("[TRANSFER] - Removing house id '{}' from owner GUID '{}' and transfering to new owner GUID '{}'", houseId, owner, bidder);
+ auto transferStatus = result->getNumber("transfer_status");
+ if (transferStatus) {
+ house->setOwner(bidder);
+ IOLoginData::increaseBankBalance(owner, internalBid);
+ } else {
+ house->setOwner(owner);
+ }
+ bidder = 0;
+ bidderName = "";
+ internalBid = 0;
+ bidEndDate = 0;
+ } else if (state == CyclopediaHouseState::MoveOut && timeNow > bidEndDate) {
g_logger().debug("[MOVE OUT] - Removing house id '{}' owner", houseId);
house->setOwner(0);
bidEndDate = 0;
@@ -357,11 +370,12 @@ bool IOMapSerialize::SaveHouseInfoGuard() {
Database &db = Database::getInstance();
std::ostringstream query;
- DBInsert houseUpdate("INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`, `bidder`, `bidder_name`, `highest_bid`, `internal_bid`, `bid_end_date`, `state`) VALUES ");
- houseUpdate.upsert({ "owner", "paid", "warnings", "name", "town_id", "rent", "size", "beds", "bidder", "bidder_name", "highest_bid", "internal_bid", "bid_end_date", "state" });
+ DBInsert houseUpdate("INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`, `bidder`, `bidder_name`, `highest_bid`, `internal_bid`, `bid_end_date`, `state`, `transfer_status`) VALUES ");
+ houseUpdate.upsert({ "owner", "paid", "warnings", "name", "town_id", "rent", "size", "beds", "bidder", "bidder_name", "highest_bid", "internal_bid", "bid_end_date", "state", "transfer_status" });
for (const auto &[key, house] : g_game().map.houses.getHouses()) {
- std::string values = fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}", house->getId(), house->getOwner(), house->getPaidUntil(), house->getPayRentWarnings(), db.escapeString(house->getName()), house->getTownId(), house->getRent(), house->getSize(), house->getBedCount(), house->getBidder(), db.escapeString(house->getBidderName()), house->getHighestBid(), house->getInternalBid(), house->getBidEndDate(), house->getState());
+ auto stateValue = magic_enum::enum_integer(house->getState());
+ std::string values = fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}", house->getId(), house->getOwner(), house->getPaidUntil(), house->getPayRentWarnings(), db.escapeString(house->getName()), house->getTownId(), house->getRent(), house->getSize(), house->getBedCount(), house->getBidder(), db.escapeString(house->getBidderName()), house->getHighestBid(), house->getInternalBid(), house->getBidEndDate(), std::to_string(stateValue), (house->getTransferStatus() ? 1 : 0));
if (!houseUpdate.addRow(values)) {
return false;
diff --git a/src/map/house/house.cpp b/src/map/house/house.cpp
index 1c985cc562e..8fdbd4c9e7d 100644
--- a/src/map/house/house.cpp
+++ b/src/map/house/house.cpp
@@ -90,7 +90,7 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, const std::
Database &db = Database::getInstance();
std::ostringstream query;
- query << "UPDATE `houses` SET `owner` = " << guid << ", `new_owner` = -1, `paid` = 0, `bidder` = 0, `bidder_name` = '', `highest_bid` = 0, `internal_bid` = 0, `bid_end_date` = 0, `state` = 0 WHERE `id` = " << id;
+ query << "UPDATE `houses` SET `owner` = " << guid << ", `new_owner` = -1, `paid` = 0, `bidder` = 0, `bidder_name` = '', `highest_bid` = 0, `internal_bid` = 0, `bid_end_date` = 0, `state` = " << (guid > 0 ? 2 : 0) << " WHERE `id` = " << id;
db.executeQuery(query.str());
}
@@ -140,7 +140,7 @@ void House::setOwner(uint32_t guid, bool updateDatabase /* = true*/, const std::
owner = guid;
ownerName = name;
ownerAccountId = result->getNumber("account_id");
- m_state = 2;
+ m_state = CyclopediaHouseState::Rented;
}
}
diff --git a/src/map/house/house.hpp b/src/map/house/house.hpp
index f67ecca5c6a..edbf6cced04 100644
--- a/src/map/house/house.hpp
+++ b/src/map/house/house.hpp
@@ -13,6 +13,7 @@
#include "declarations.hpp"
#include "map/house/housetile.hpp"
#include "game/movement/position.hpp"
+#include "enums/player_cyclopedia.hpp"
class House;
class BedItem;
@@ -285,13 +286,20 @@ class House final : public SharedObject {
return m_bidEndDate;
}
- void setState(uint8_t state) {
+ void setState(CyclopediaHouseState state) {
this->m_state = state;
}
- uint8_t getState() const {
+ CyclopediaHouseState getState() const {
return m_state;
}
+ void setTransferStatus(bool transferStatus) {
+ this->m_transferStatus = transferStatus;
+ }
+ bool getTransferStatus () const {
+ return m_transferStatus;
+ }
+
void setOwnerAccountId(uint32_t accountId) {
this->ownerAccountId = accountId;
}
@@ -348,7 +356,8 @@ class House final : public SharedObject {
uint64_t m_internalBid = 0;
uint64_t m_bidHolderLimit = 0;
uint32_t m_bidEndDate = 0;
- uint8_t m_state = 0;
+ CyclopediaHouseState m_state = CyclopediaHouseState::Available;
+ bool m_transferStatus = false;
bool isLoaded = false;
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index ce36bdb2bd1..3816f82b3d1 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -39,6 +39,7 @@
#include "enums/account_group_type.hpp"
#include "enums/account_coins.hpp"
#include "enums/player_blessings.hpp"
+#include "enums/player_cyclopedia.hpp"
#include "creatures/players/highscore_category.hpp"
@@ -9282,6 +9283,11 @@ void ProtocolGame::parseCyclopediaHouseAuction(NetworkMessage &msg) {
break;
}
case 3: {
+ const uint32_t houseId = msg.get();
+ const uint32_t timestamp = msg.get();
+ const std::string &newOwner = msg.getString();
+ const uint64_t bidValue = msg.get();
+ g_game().playerCyclopediaHouseTransfer(player->getID(), houseId, timestamp, newOwner, bidValue);
break;
}
case 4: {
@@ -9289,6 +9295,21 @@ void ProtocolGame::parseCyclopediaHouseAuction(NetworkMessage &msg) {
g_game().playerCyclopediaHouseCancelMoveOut(player->getID(), houseId);
break;
}
+ case 5: {
+ const uint32_t houseId = msg.get();
+ g_game().playerCyclopediaHouseCancelTransfer(player->getID(), houseId);
+ break;
+ }
+ case 6: {
+ const uint32_t houseId = msg.get();
+ g_game().playerCyclopediaHouseAcceptTransfer(player->getID(), houseId);
+ break;
+ }
+ case 7: {
+ const uint32_t houseId = msg.get();
+ g_game().playerCyclopediaHouseRejectTransfer(player->getID(), houseId);
+ break;
+ }
}
}
@@ -9300,8 +9321,10 @@ void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
msg.add(clientId);
msg.addByte(0x01); // 0x00 = Renovation; 0x01 = Available
- msg.addByte(houseData->getState());
- if (houseData->getState() == 0) { // Available
+ auto houseState = houseData->getState();
+ auto stateValue = magic_enum::enum_integer(houseState);
+ msg.addByte(stateValue);
+ if (houseState == CyclopediaHouseState::Available) {
bool bidder = houseData->getBidderName() == player->getName();
msg.addString(houseData->getBidderName());
msg.addByte(bidder ? 1 : 0);
@@ -9315,7 +9338,7 @@ void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
msg.add(houseData->getBidHolderLimit());
}
}
- } else if (houseData->getState() == 2) { // Rented
+ } else if (houseState == CyclopediaHouseState::Rented) {
auto ownerName = IOLoginData::getNameByGuid(houseData->getOwner());
msg.addString(ownerName);
msg.add(houseData->getPaidUntil());
@@ -9326,7 +9349,33 @@ void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
msg.addByte(0);
msg.addByte(0);
}
- } else if (houseData->getState() == 4) { // Move Out
+ } else if (houseState == CyclopediaHouseState::Transfer) {
+ auto ownerName = IOLoginData::getNameByGuid(houseData->getOwner());
+ msg.addString(ownerName);
+ msg.add(houseData->getPaidUntil());
+
+ bool isOwner = ownerName.compare(player->getName()) == 0;
+ msg.addByte(isOwner);
+ if (isOwner) {
+ msg.addByte(0); // ?
+ msg.addByte(0); // ?
+ }
+ msg.add(houseData->getBidEndDate());
+ msg.addString(houseData->getBidderName());
+ msg.addByte(0); // ?
+ msg.add(houseData->getInternalBid());
+
+ bool isNewOwner = player->getName() == houseData->getBidderName();
+ msg.addByte(isNewOwner);
+ if (isNewOwner) {
+ msg.addByte(0); // Accept Transfer Error
+ msg.addByte(0); // Reject Transfer Error
+ }
+
+ if (isOwner) {
+ msg.addByte(0); // Cancel Transfer Error
+ }
+ } else if (houseState == CyclopediaHouseState::MoveOut) {
auto ownerName = IOLoginData::getNameByGuid(houseData->getOwner());
msg.addString(ownerName);
msg.add(houseData->getPaidUntil());
From 95c16ed88ceb31d40954f749176538a18341d9a5 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Wed, 30 Oct 2024 19:00:12 +0000
Subject: [PATCH 10/28] Code format - (Clang-format)
---
src/map/house/house.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/map/house/house.hpp b/src/map/house/house.hpp
index edbf6cced04..d994fdbe3b2 100644
--- a/src/map/house/house.hpp
+++ b/src/map/house/house.hpp
@@ -296,7 +296,7 @@ class House final : public SharedObject {
void setTransferStatus(bool transferStatus) {
this->m_transferStatus = transferStatus;
}
- bool getTransferStatus () const {
+ bool getTransferStatus() const {
return m_transferStatus;
}
From 19ce3959123298b557630447accef48cdbb14745 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 16:02:28 -0300
Subject: [PATCH 11/28] missing column schema.sql
---
schema.sql | 1 +
1 file changed, 1 insertion(+)
diff --git a/schema.sql b/schema.sql
index 821b3bcff41..3b63cc67cb7 100644
--- a/schema.sql
+++ b/schema.sql
@@ -461,6 +461,7 @@ CREATE TABLE IF NOT EXISTS `houses` (
`internal_bid` int(11) NOT NULL DEFAULT '0',
`bid_end_date` int(11) NOT NULL DEFAULT '0',
`state` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
+ `transfer_status` tinyint(1) DEFAULT '0',
INDEX `owner` (`owner`),
INDEX `town_id` (`town_id`),
CONSTRAINT `houses_pk` PRIMARY KEY (`id`)
From 1a8c7617db4410f34f0197a3fb32dec24edf3182 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 18:24:46 -0300
Subject: [PATCH 12/28] some fixes
---
src/game/game.cpp | 22 ++++++++++++++++++++++
src/io/iomapserialize.cpp | 4 +++-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 63a5dc4df98..bf05e2c7173 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10979,6 +10979,17 @@ void Game::playerCyclopediaHouseCancelTransfer(uint32_t playerId, uint32_t house
return;
}
+ if (house->getTransferStatus()) {
+ const auto &newOwner = getPlayerByGUID(house->getBidder());
+ const auto amountPaid = house->getInternalBid() + house->getRent();
+ if (newOwner) {
+ newOwner->setBankBalance(newOwner->getBankBalance() + amountPaid);
+ newOwner->sendResourceBalance(RESOURCE_BANK, newOwner->getBankBalance());
+ } else {
+ IOLoginData::increaseBankBalance(house->getBidder(), amountPaid);
+ }
+ }
+
house->setBidderName("");
house->setBidder(0);
house->setInternalBid(0);
@@ -11028,6 +11039,17 @@ void Game::playerCyclopediaHouseRejectTransfer(uint32_t playerId, uint32_t house
return;
}
+ if (house->getTransferStatus()) {
+ const auto &newOwner = getPlayerByGUID(house->getBidder());
+ const auto amountPaid = house->getInternalBid() + house->getRent();
+ if (newOwner) {
+ newOwner->setBankBalance(newOwner->getBankBalance() + amountPaid);
+ newOwner->sendResourceBalance(RESOURCE_BANK, newOwner->getBankBalance());
+ } else {
+ IOLoginData::increaseBankBalance(house->getBidder(), amountPaid);
+ }
+ }
+
house->setBidderName("");
house->setBidder(0);
house->setInternalBid(0);
diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp
index 2e3c0c9d16a..3857af533d0 100644
--- a/src/io/iomapserialize.cpp
+++ b/src/io/iomapserialize.cpp
@@ -288,6 +288,7 @@ bool IOMapSerialize::loadHouseInfo() {
uint32_t internalBid = result->getNumber("internal_bid");
uint32_t bidEndDate = result->getNumber("bid_end_date");
auto state = static_cast(result->getNumber("state"));
+ auto transferStatus = result->getNumber("transfer_status");
const auto timeNow = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count();
// Transfer house owner
auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART);
@@ -314,7 +315,6 @@ bool IOMapSerialize::loadHouseInfo() {
bidEndDate = 0;
} else if (state == CyclopediaHouseState::Transfer && timeNow > bidEndDate && bidder > 0) {
g_logger().debug("[TRANSFER] - Removing house id '{}' from owner GUID '{}' and transfering to new owner GUID '{}'", houseId, owner, bidder);
- auto transferStatus = result->getNumber("transfer_status");
if (transferStatus) {
house->setOwner(bidder);
IOLoginData::increaseBankBalance(owner, internalBid);
@@ -325,6 +325,7 @@ bool IOMapSerialize::loadHouseInfo() {
bidderName = "";
internalBid = 0;
bidEndDate = 0;
+ transferStatus = false;
} else if (state == CyclopediaHouseState::MoveOut && timeNow > bidEndDate) {
g_logger().debug("[MOVE OUT] - Removing house id '{}' owner", houseId);
house->setOwner(0);
@@ -339,6 +340,7 @@ bool IOMapSerialize::loadHouseInfo() {
house->setInternalBid(internalBid);
house->setBidHolderLimit(internalBid);
house->setBidEndDate(bidEndDate);
+ house->setTransferStatus(transferStatus);
}
} while (result->next());
From aab4b95727e78ca3fb8c5a148eb0d68051e43194 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 18:25:14 -0300
Subject: [PATCH 13/28] error handling
---
src/creatures/players/player.cpp | 63 ++++++++++++++++++++
src/creatures/players/player.hpp | 2 +
src/enums/player_cyclopedia.hpp | 29 +++++++++
src/game/game.cpp | 55 +++++++++++++++--
src/server/network/protocol/protocolgame.cpp | 3 +-
5 files changed, 146 insertions(+), 6 deletions(-)
diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp
index 76b3b84fe1e..ca8107b4eb1 100644
--- a/src/creatures/players/player.cpp
+++ b/src/creatures/players/player.cpp
@@ -8304,3 +8304,66 @@ BidErrorMessage Player::canBidHouse(uint32_t houseId) {
return BidErrorMessage::NoError;
}
+
+TransferErrorMessage Player::canTransferHouse(uint32_t houseId, uint32_t newOwnerGUID) {
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house) {
+ return TransferErrorMessage::Internal;
+ }
+
+ if (getGUID() != house->getOwner()) {
+ return TransferErrorMessage::NotHouseOwner;
+ }
+
+ if (getGUID() == newOwnerGUID) {
+ return TransferErrorMessage::AlreadyTheOwner;
+ }
+
+ const auto newOwner = g_game().getPlayerByGUID(newOwnerGUID, true);
+ if (!newOwner) {
+ return TransferErrorMessage::CharacterNotExist;
+ }
+
+ if (newOwner->getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
+ return TransferErrorMessage::Rookgaard;
+ }
+
+ if (!newOwner->isPremium()) {
+ return TransferErrorMessage::Premium;
+ }
+
+ if (newOwner->getAccount()->getHouseBidId() != 0) {
+ return TransferErrorMessage::OnlyOneBid;
+ }
+
+ return TransferErrorMessage::Success;
+}
+
+AcceptTransferErrorMessage Player::canAcceptTransferHouse(uint32_t houseId) {
+ const auto house = g_game().map.houses.getHouseByClientId(houseId);
+ if (!house) {
+ return AcceptTransferErrorMessage::Internal;
+ }
+
+ if (getGUID() != house->getBidder()) {
+ return AcceptTransferErrorMessage::NotNewOwner;
+ }
+
+ if (!isPremium()) {
+ return AcceptTransferErrorMessage::Premium;
+ }
+
+ if (getAccount()->getHouseBidId() != 0) {
+ return AcceptTransferErrorMessage::AlreadyBid;
+ }
+
+ if (getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
+ return AcceptTransferErrorMessage::Rookgaard;
+ }
+
+ if (house->getTransferStatus()) {
+ return AcceptTransferErrorMessage::AlreadyAccepted;
+ }
+
+ return AcceptTransferErrorMessage::Success;
+}
\ No newline at end of file
diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp
index fca0aedcaaf..de257a1717d 100644
--- a/src/creatures/players/player.hpp
+++ b/src/creatures/players/player.hpp
@@ -1576,6 +1576,8 @@ class Player final : public Creature, public Cylinder, public Bankable {
}
BidErrorMessage canBidHouse(uint32_t houseId);
+ TransferErrorMessage canTransferHouse(uint32_t houseId, uint32_t newOwnerGUID);
+ AcceptTransferErrorMessage canAcceptTransferHouse(uint32_t houseId);
void sendCyclopediaHouseList(const HouseMap &houses) {
if (client) {
client->sendCyclopediaHouseList(houses);
diff --git a/src/enums/player_cyclopedia.hpp b/src/enums/player_cyclopedia.hpp
index 3c515df8b66..1a2813324ca 100644
--- a/src/enums/player_cyclopedia.hpp
+++ b/src/enums/player_cyclopedia.hpp
@@ -71,6 +71,11 @@ enum class CyclopediaHouseState : uint8_t {
enum class HouseAuctionType : uint8_t {
Bid = 1,
MoveOut = 2,
+ Transfer = 3,
+ CancelMoveOut = 4,
+ CancelTransfer = 5,
+ AcceptTransfer = 6,
+ RejectTransfer = 7,
};
enum class BidSuccessMessage : uint8_t {
@@ -88,3 +93,27 @@ enum class BidErrorMessage : uint8_t {
NotEnoughGuildMoney = 21,
Internal = 24,
};
+
+// Bytes to:
+// Move Out, Transfer
+// Cancel Move Out/Transfer
+enum class TransferErrorMessage : uint8_t {
+ Success = 0,
+ NotHouseOwner = 2,
+ CharacterNotExist = 4,
+ Premium = 7,
+ Rookgaard = 16,
+ AlreadyTheOwner = 19,
+ OnlyOneBid = 25,
+ Internal = 32,
+};
+
+enum class AcceptTransferErrorMessage : uint8_t {
+ Success = 0,
+ NotNewOwner = 2,
+ AlreadyBid = 3,
+ AlreadyAccepted = 7,
+ Rookgaard = 8,
+ Premium = 9,
+ Internal = 19,
+};
\ No newline at end of file
diff --git a/src/game/game.cpp b/src/game/game.cpp
index bf05e2c7173..e2e0006ab0f 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10900,17 +10900,25 @@ void Game::playerCyclopediaHouseMoveOut(uint32_t playerId, uint32_t houseId, uin
std::shared_ptr player = getPlayerByID(playerId);
if (!player) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::MoveOut, enumToValue(TransferErrorMessage::Internal));
return;
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getOwner() != player->getGUID() || house->getState() != CyclopediaHouseState::Rented) {
+ if (!house || house->getState() != CyclopediaHouseState::Rented) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::MoveOut, enumToValue(TransferErrorMessage::Internal));
+ return;
+ }
+
+ if (house->getOwner() != player->getGUID()) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::MoveOut, enumToValue(TransferErrorMessage::NotHouseOwner));
return;
}
house->setBidEndDate(timestamp);
house->setState(CyclopediaHouseState::MoveOut);
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::MoveOut, enumToValue(TransferErrorMessage::Success));
playerCyclopediaHousesByTown(playerId, "");
}
@@ -10921,17 +10929,25 @@ void Game::playerCyclopediaHouseCancelMoveOut(uint32_t playerId, uint32_t houseI
std::shared_ptr player = getPlayerByID(playerId);
if (!player) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::CancelMoveOut, enumToValue(TransferErrorMessage::Internal));
return;
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getOwner() != player->getGUID() || house->getState() != CyclopediaHouseState::MoveOut) {
+ if (!house || house->getState() != CyclopediaHouseState::MoveOut) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::CancelMoveOut, enumToValue(TransferErrorMessage::Internal));
+ return;
+ }
+
+ if (house->getOwner() != player->getGUID()) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::CancelMoveOut, enumToValue(TransferErrorMessage::NotHouseOwner));
return;
}
house->setBidEndDate(0);
house->setState(CyclopediaHouseState::Rented);
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::CancelMoveOut, enumToValue(TransferErrorMessage::Success));
playerCyclopediaHousesByTown(playerId, "");
}
@@ -10942,16 +10958,25 @@ void Game::playerCyclopediaHouseTransfer(uint32_t playerId, uint32_t houseId, ui
const std::shared_ptr &owner = getPlayerByID(playerId);
if (!owner) {
+ owner->sendHouseAuctionMessage(houseId, HouseAuctionType::Transfer, enumToValue(TransferErrorMessage::Internal));
return;
}
const std::shared_ptr &newOwner = getPlayerByName(newOwnerName, true);
if (!newOwner) {
+ owner->sendHouseAuctionMessage(houseId, HouseAuctionType::Transfer, enumToValue(TransferErrorMessage::CharacterNotExist));
return;
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getOwner() != owner->getGUID() || house->getState() != CyclopediaHouseState::Rented) {
+ if (!house || house->getState() != CyclopediaHouseState::Rented) {
+ owner->sendHouseAuctionMessage(houseId, HouseAuctionType::Transfer, enumToValue(TransferErrorMessage::Internal));
+ return;
+ }
+
+ auto ret = owner->canTransferHouse(houseId, newOwner->getGUID());
+ if (ret != TransferErrorMessage::Success) {
+ owner->sendHouseAuctionMessage(houseId, HouseAuctionType::Transfer, enumToValue(ret));
return;
}
@@ -10961,6 +10986,7 @@ void Game::playerCyclopediaHouseTransfer(uint32_t playerId, uint32_t houseId, ui
house->setBidEndDate(timestamp);
house->setState(CyclopediaHouseState::Transfer);
+ owner->sendHouseAuctionMessage(houseId, HouseAuctionType::Transfer, enumToValue(ret));
playerCyclopediaHousesByTown(playerId, "");
}
@@ -10971,11 +10997,18 @@ void Game::playerCyclopediaHouseCancelTransfer(uint32_t playerId, uint32_t house
const std::shared_ptr &player = getPlayerByID(playerId);
if (!player) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::CancelTransfer, enumToValue(TransferErrorMessage::Internal));
return;
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getOwner() != player->getGUID() || house->getState() != CyclopediaHouseState::Transfer) {
+ if (!house || house->getState() != CyclopediaHouseState::Transfer) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::CancelTransfer, enumToValue(TransferErrorMessage::Internal));
+ return;
+ }
+
+ if (house->getOwner() != player->getGUID()) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::CancelTransfer, enumToValue(TransferErrorMessage::NotHouseOwner));
return;
}
@@ -10997,6 +11030,7 @@ void Game::playerCyclopediaHouseCancelTransfer(uint32_t playerId, uint32_t house
house->setState(CyclopediaHouseState::Rented);
house->setTransferStatus(false);
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::CancelTransfer, enumToValue(TransferErrorMessage::Success));
playerCyclopediaHousesByTown(playerId, "");
}
@@ -11007,11 +11041,18 @@ void Game::playerCyclopediaHouseAcceptTransfer(uint32_t playerId, uint32_t house
const std::shared_ptr &player = getPlayerByID(playerId);
if (!player) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::AcceptTransfer, enumToValue(AcceptTransferErrorMessage::Internal));
return;
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
- if (!house || house->getBidder() != player->getGUID() || house->getState() != CyclopediaHouseState::Transfer) {
+ if (!house || house->getState() != CyclopediaHouseState::Transfer) {
+ return;
+ }
+
+ auto ret = player->canAcceptTransferHouse(houseId);
+ if (ret != AcceptTransferErrorMessage::Success) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::AcceptTransfer, enumToValue(ret));
return;
}
@@ -11021,6 +11062,7 @@ void Game::playerCyclopediaHouseAcceptTransfer(uint32_t playerId, uint32_t house
house->setTransferStatus(true);
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::AcceptTransfer, enumToValue(ret));
playerCyclopediaHousesByTown(playerId, "");
}
@@ -11031,11 +11073,13 @@ void Game::playerCyclopediaHouseRejectTransfer(uint32_t playerId, uint32_t house
const std::shared_ptr &player = getPlayerByID(playerId);
if (!player) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::Transfer, enumToValue(TransferErrorMessage::Internal));
return;
}
const auto house = g_game().map.houses.getHouseByClientId(houseId);
if (!house || house->getBidder() != player->getGUID() || house->getState() != CyclopediaHouseState::Transfer) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::Transfer, enumToValue(TransferErrorMessage::NotHouseOwner));
return;
}
@@ -11057,6 +11101,7 @@ void Game::playerCyclopediaHouseRejectTransfer(uint32_t playerId, uint32_t house
house->setState(CyclopediaHouseState::Rented);
house->setTransferStatus(false);
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::RejectTransfer, enumToValue(TransferErrorMessage::Success));
playerCyclopediaHousesByTown(playerId, "");
}
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index 3816f82b3d1..78f5120eda7 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -9368,7 +9368,8 @@ void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
bool isNewOwner = player->getName() == houseData->getBidderName();
msg.addByte(isNewOwner);
if (isNewOwner) {
- msg.addByte(0); // Accept Transfer Error
+ uint8_t disableIndex = enumToValue(player->canAcceptTransferHouse(clientId));
+ msg.addByte(disableIndex); // Accept Transfer Error
msg.addByte(0); // Reject Transfer Error
}
From f53b628eac3c0937fab31d1456f70dfa77b3d5b3 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Wed, 30 Oct 2024 21:26:30 +0000
Subject: [PATCH 14/28] Code format - (Clang-format)
---
src/creatures/players/player.cpp | 2 +-
src/enums/player_cyclopedia.hpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp
index ca8107b4eb1..ae43e3e338e 100644
--- a/src/creatures/players/player.cpp
+++ b/src/creatures/players/player.cpp
@@ -8366,4 +8366,4 @@ AcceptTransferErrorMessage Player::canAcceptTransferHouse(uint32_t houseId) {
}
return AcceptTransferErrorMessage::Success;
-}
\ No newline at end of file
+}
diff --git a/src/enums/player_cyclopedia.hpp b/src/enums/player_cyclopedia.hpp
index 1a2813324ca..9df484e417d 100644
--- a/src/enums/player_cyclopedia.hpp
+++ b/src/enums/player_cyclopedia.hpp
@@ -116,4 +116,4 @@ enum class AcceptTransferErrorMessage : uint8_t {
Rookgaard = 8,
Premium = 9,
Internal = 19,
-};
\ No newline at end of file
+};
From f3667aacda218b530c43a34c4b41bbead3643e39 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 18:45:22 -0300
Subject: [PATCH 15/28] missing errors
---
src/creatures/players/player.cpp | 4 ++++
src/enums/player_cyclopedia.hpp | 1 +
src/game/game.cpp | 2 ++
src/server/network/protocol/protocolgame.cpp | 2 +-
4 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp
index ae43e3e338e..67b1587dd84 100644
--- a/src/creatures/players/player.cpp
+++ b/src/creatures/players/player.cpp
@@ -8361,6 +8361,10 @@ AcceptTransferErrorMessage Player::canAcceptTransferHouse(uint32_t houseId) {
return AcceptTransferErrorMessage::Rookgaard;
}
+ if (getBankBalance() < (house->getRent() + house->getInternalBid())) {
+ return AcceptTransferErrorMessage::Frozen;
+ }
+
if (house->getTransferStatus()) {
return AcceptTransferErrorMessage::AlreadyAccepted;
}
diff --git a/src/enums/player_cyclopedia.hpp b/src/enums/player_cyclopedia.hpp
index 9df484e417d..4d2227f8d48 100644
--- a/src/enums/player_cyclopedia.hpp
+++ b/src/enums/player_cyclopedia.hpp
@@ -115,5 +115,6 @@ enum class AcceptTransferErrorMessage : uint8_t {
AlreadyAccepted = 7,
Rookgaard = 8,
Premium = 9,
+ Frozen = 15,
Internal = 19,
};
diff --git a/src/game/game.cpp b/src/game/game.cpp
index e2e0006ab0f..121a598402d 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -11047,6 +11047,7 @@ void Game::playerCyclopediaHouseAcceptTransfer(uint32_t playerId, uint32_t house
const auto house = g_game().map.houses.getHouseByClientId(houseId);
if (!house || house->getState() != CyclopediaHouseState::Transfer) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::AcceptTransfer, enumToValue(AcceptTransferErrorMessage::Internal));
return;
}
@@ -11057,6 +11058,7 @@ void Game::playerCyclopediaHouseAcceptTransfer(uint32_t playerId, uint32_t house
}
if (!processBankAuction(player, house, house->getInternalBid())) {
+ player->sendHouseAuctionMessage(houseId, HouseAuctionType::AcceptTransfer, enumToValue(AcceptTransferErrorMessage::Frozen));
return;
}
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index 78f5120eda7..3bf79d51e64 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -9327,7 +9327,7 @@ void ProtocolGame::sendCyclopediaHouseList(HouseMap houses) {
if (houseState == CyclopediaHouseState::Available) {
bool bidder = houseData->getBidderName() == player->getName();
msg.addString(houseData->getBidderName());
- msg.addByte(bidder ? 1 : 0);
+ msg.addByte(bidder);
uint8_t disableIndex = enumToValue(player->canBidHouse(clientId));
msg.addByte(disableIndex);
From cbbdc2d4e79e5155dcf2d66c353244bb20d6d514 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 19:18:07 -0300
Subject: [PATCH 16/28] configurable days to close bid
---
config.lua.dist | 1 +
src/config/config_enums.hpp | 1 +
src/config/configmanager.cpp | 1 +
src/game/game.cpp | 2 +-
4 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/config.lua.dist b/config.lua.dist
index 5e8918452f5..7c891c84b5d 100644
--- a/config.lua.dist
+++ b/config.lua.dist
@@ -345,6 +345,7 @@ Setting this to false may pose risks; if a house is abandoned and contains a lar
-- Periods: daily/weekly/monthly/yearly/never
-- Base: sqm,rent,sqm+rent
toggleCyclopediaHouseAuction = true
+daysToCloseBid = 7
housePriceRentMultiplier = 0.0
housePriceEachSQM = 1000
houseRentPeriod = "monthly"
diff --git a/src/config/config_enums.hpp b/src/config/config_enums.hpp
index a3294d692dc..65e585159e8 100644
--- a/src/config/config_enums.hpp
+++ b/src/config/config_enums.hpp
@@ -111,6 +111,7 @@ enum ConfigKey_t : uint16_t {
HAZARD_PODS_TIME_TO_DAMAGE,
HAZARD_PODS_TIME_TO_SPAWN,
HAZARD_SPAWN_PLUNDER_MULTIPLIER,
+ DAYS_TO_CLOSE_BID,
HOUSE_BUY_LEVEL,
HOUSE_LOSE_AFTER_INACTIVITY,
HOUSE_OWNED_BY_ACCOUNT,
diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp
index f5bafa4fbc3..c060a44e07b 100644
--- a/src/config/configmanager.cpp
+++ b/src/config/configmanager.cpp
@@ -254,6 +254,7 @@ bool ConfigManager::load() {
loadIntConfig(L, HAZARD_PODS_TIME_TO_DAMAGE, "hazardPodsTimeToDamage", 2000);
loadIntConfig(L, HAZARD_PODS_TIME_TO_SPAWN, "hazardPodsTimeToSpawn", 4000);
loadIntConfig(L, HAZARD_SPAWN_PLUNDER_MULTIPLIER, "hazardSpawnPlunderMultiplier", 25);
+ loadIntConfig(L, DAYS_TO_CLOSE_BID, "daysToCloseBid", 7);
loadIntConfig(L, HOUSE_BUY_LEVEL, "houseBuyLevel", 0);
loadIntConfig(L, HOUSE_LOSE_AFTER_INACTIVITY, "houseLoseAfterInactivity", 0);
loadIntConfig(L, HOUSE_PRICE_PER_SQM, "housePriceEachSQM", 1000);
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 121a598402d..97eff18b212 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10860,7 +10860,7 @@ void Game::playerCyclopediaHouseBid(uint32_t playerId, uint32_t houseId, uint64_
house->setBidHolderLimit(bidValue);
house->setBidderName(player->getName());
house->setBidder(player->getGUID());
- house->calculateBidEndDate(7);
+ house->calculateBidEndDate(g_configManager().getNumber(DAYS_TO_CLOSE_BID));
} else if (house->getBidderName() == player->getName()) {
if (!processBankAuction(player, house, bidValue, true)) {
player->sendHouseAuctionMessage(houseId, HouseAuctionType::Bid, enumToValue(ret));
From 798ece791bda0170a9c8c61a8ad583dea079d054 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 19:48:23 -0300
Subject: [PATCH 17/28] fix compilation
---
src/account/account.cpp | 4 ++--
src/creatures/players/player.cpp | 17 +++++++++++++
src/creatures/players/player.hpp | 25 ++++++++------------
src/server/network/protocol/protocolgame.cpp | 1 +
src/server/network/protocol/protocolgame.hpp | 2 ++
5 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/src/account/account.cpp b/src/account/account.cpp
index 1a0419431e2..221e7fdb705 100644
--- a/src/account/account.cpp
+++ b/src/account/account.cpp
@@ -297,8 +297,8 @@ uint32_t Account::getAccountAgeInDays() const {
}
uint32_t Account::getHouseBidId() const {
- return m_account.houseBidId;
+ return m_account->houseBidId;
}
void Account::setHouseBidId(uint32_t houseId) {
- m_account.houseBidId = houseId;
+ m_account->houseBidId = houseId;
}
diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp
index fe611b0c2c7..6cb69074a85 100644
--- a/src/creatures/players/player.cpp
+++ b/src/creatures/players/player.cpp
@@ -36,6 +36,7 @@
#include "enums/object_category.hpp"
#include "enums/player_blessings.hpp"
#include "enums/player_icons.hpp"
+#include "enums/player_cyclopedia.hpp"
#include "game/game.hpp"
#include "game/modal_window/modal_window.hpp"
#include "game/scheduling/dispatcher.hpp"
@@ -2264,6 +2265,22 @@ void Player::sendOutfitWindow() const {
}
}
+void Player::sendCyclopediaHouseList(const HouseMap &houses) const {
+ if (client) {
+ client->sendCyclopediaHouseList(houses);
+ }
+}
+void Player::sendResourceBalance(Resource_t resourceType, uint64_t value) const {
+ if (client) {
+ client->sendResourceBalance(resourceType, value);
+ }
+}
+void Player::sendHouseAuctionMessage(uint32_t houseId, HouseAuctionType type, uint8_t index, bool bidSuccess /* = false*/) const {
+ if (client) {
+ client->sendHouseAuctionMessage(houseId, type, index, bidSuccess);
+ }
+}
+
// Imbuements
void Player::onApplyImbuement(const Imbuement* imbuement, const std::shared_ptr
- &item, uint8_t slot, bool protectionCharm) {
diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp
index 26f50137851..898e0b0e2b1 100644
--- a/src/creatures/players/player.hpp
+++ b/src/creatures/players/player.hpp
@@ -64,17 +64,23 @@ struct HighscoreCharacter;
enum class PlayerIcon : uint8_t;
enum class IconBakragore : uint8_t;
+enum class HouseAuctionType : uint8_t;
+enum class BidErrorMessage : uint8_t;
+enum class TransferErrorMessage : uint8_t;
+enum class AcceptTransferErrorMessage : uint8_t;
enum ObjectCategory_t : uint8_t;
enum PreySlot_t : uint8_t;
enum SpeakClasses : uint8_t;
enum ChannelEvent_t : uint8_t;
enum SquareColor_t : uint8_t;
+enum Resource_t : uint8_t;
using GuildWarVector = std::vector;
using StashContainerList = std::vector, uint32_t>>;
using ItemVector = std::vector>;
using UsersMap = std::map>;
using InvitedMap = std::map>;
+using HouseMap = std::map>;
struct ForgeHistory {
ForgeAction_t actionType = ForgeAction_t::FUSION;
@@ -880,24 +886,13 @@ class Player final : public Creature, public Cylinder, public Bankable {
void sendOpenPrivateChannel(const std::string &receiver) const;
void sendExperienceTracker(int64_t rawExp, int64_t finalExp) const;
void sendOutfitWindow() const;
+ // House Auction
BidErrorMessage canBidHouse(uint32_t houseId);
TransferErrorMessage canTransferHouse(uint32_t houseId, uint32_t newOwnerGUID);
AcceptTransferErrorMessage canAcceptTransferHouse(uint32_t houseId);
- void sendCyclopediaHouseList(const HouseMap &houses) {
- if (client) {
- client->sendCyclopediaHouseList(houses);
- }
- }
- void sendResourceBalance(Resource_t resourceType, uint64_t value) {
- if (client) {
- client->sendResourceBalance(resourceType, value);
- }
- }
- void sendHouseAuctionMessage(uint32_t houseId, HouseAuctionType type, uint8_t index, bool bidSuccess = false) {
- if (client) {
- client->sendHouseAuctionMessage(houseId, type, index, bidSuccess);
- }
- }
+ void sendCyclopediaHouseList(const HouseMap &houses) const;
+ void sendResourceBalance(Resource_t resourceType, uint64_t value) const;
+ void sendHouseAuctionMessage(uint32_t houseId, HouseAuctionType type, uint8_t index, bool bidSuccess = false) const;
// Imbuements
void onApplyImbuement(const Imbuement* imbuement, const std::shared_ptr
- &item, uint8_t slot, bool protectionCharm);
void onClearImbuement(const std::shared_ptr
- &item, uint8_t slot);
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index 242c5c83f41..1ef97af8c94 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -53,6 +53,7 @@
#include "enums/account_type.hpp"
#include "enums/object_category.hpp"
#include "enums/player_blessings.hpp"
+#include "enums/player_cyclopedia.hpp"
/*
* NOTE: This namespace is used so that we can add functions without having to declare them in the ".hpp/.hpp" file
diff --git a/src/server/network/protocol/protocolgame.hpp b/src/server/network/protocol/protocolgame.hpp
index e42ae1d1ee8..22f135e05f1 100644
--- a/src/server/network/protocol/protocolgame.hpp
+++ b/src/server/network/protocol/protocolgame.hpp
@@ -29,6 +29,7 @@ enum Slots_t : uint8_t;
enum CombatType_t : uint8_t;
enum SoundEffect_t : uint16_t;
enum class SourceEffect_t : uint8_t;
+enum class HouseAuctionType : uint8_t;
class NetworkMessage;
class Player;
@@ -68,6 +69,7 @@ using MarketOfferList = std::list;
using HistoryMarketOfferList = std::list;
using ItemsTierCountList = std::map>;
using StashItemList = std::map;
+using HouseMap = std::map>;
struct TextMessage {
TextMessage() = default;
From da4398dba017dd74b8afbe20fa31b5d1ffc65eec Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 20:30:24 -0300
Subject: [PATCH 18/28] fix migration
---
data-otservbr-global/migrations/46.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/data-otservbr-global/migrations/46.lua b/data-otservbr-global/migrations/46.lua
index d1709730493..dc79c7cee35 100644
--- a/data-otservbr-global/migrations/46.lua
+++ b/data-otservbr-global/migrations/46.lua
@@ -16,7 +16,7 @@ function onUpdateDatabase()
ADD `highest_bid` int(11) NOT NULL DEFAULT '0',
ADD `internal_bid` int(11) NOT NULL DEFAULT '0',
ADD `bid_end_date` int(11) NOT NULL DEFAULT '0',
- ADD `state` smallint(5) UNSIGNED NOT NULL DEFAULT '0'
+ ADD `state` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
ADD `transfer_status` tinyint(1) DEFAULT '0'
]])
From 6a5ecf2301c88bd17cf4d3bd10c54fbddb2f6c2b Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Wed, 30 Oct 2024 20:41:12 -0300
Subject: [PATCH 19/28] sonar issue
---
src/io/iomapserialize.cpp | 121 +++++++++++++++++++-------------------
1 file changed, 62 insertions(+), 59 deletions(-)
diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp
index 0757095fc8e..c54f39f99b4 100644
--- a/src/io/iomapserialize.cpp
+++ b/src/io/iomapserialize.cpp
@@ -281,69 +281,72 @@ bool IOMapSerialize::loadHouseInfo() {
do {
auto houseId = result->getNumber("id");
const auto house = g_game().map.houses.getHouse(houseId);
- if (house) {
- auto owner = result->getNumber("owner");
- auto newOwner = result->getNumber("new_owner");
- uint32_t bidder = result->getNumber("bidder");
- std::string bidderName = result->getString("bidder_name");
- uint32_t highestBid = result->getNumber("highest_bid");
- uint32_t internalBid = result->getNumber("internal_bid");
- uint32_t bidEndDate = result->getNumber("bid_end_date");
- auto state = static_cast(result->getNumber("state"));
- auto transferStatus = result->getNumber("transfer_status");
- const auto timeNow = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count();
- // Transfer house owner
- auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART);
- if (isTransferOnRestart && newOwner >= 0) {
- g_game().setTransferPlayerHouseItems(houseId, owner);
- if (newOwner == 0) {
- g_logger().debug("Removing house id '{}' owner", houseId);
- house->setOwner(0);
- } else {
- g_logger().debug("Setting house id '{}' owner to player GUID '{}'", houseId, newOwner);
- house->setOwner(newOwner);
- }
- } else if (state == CyclopediaHouseState::Available && timeNow > bidEndDate && bidder > 0) {
- g_logger().debug("[BID] - Setting house id '{}' owner to player GUID '{}'", houseId, bidder);
- if (highestBid < internalBid) {
- uint32_t diff = internalBid - highestBid;
- IOLoginData::increaseBankBalance(bidder, diff);
- }
- house->setOwner(bidder);
- bidder = 0;
- bidderName = "";
- highestBid = 0;
- internalBid = 0;
- bidEndDate = 0;
- } else if (state == CyclopediaHouseState::Transfer && timeNow > bidEndDate && bidder > 0) {
- g_logger().debug("[TRANSFER] - Removing house id '{}' from owner GUID '{}' and transfering to new owner GUID '{}'", houseId, owner, bidder);
- if (transferStatus) {
- house->setOwner(bidder);
- IOLoginData::increaseBankBalance(owner, internalBid);
- } else {
- house->setOwner(owner);
- }
- bidder = 0;
- bidderName = "";
- internalBid = 0;
- bidEndDate = 0;
- transferStatus = false;
- } else if (state == CyclopediaHouseState::MoveOut && timeNow > bidEndDate) {
- g_logger().debug("[MOVE OUT] - Removing house id '{}' owner", houseId);
+ if (!house) {
+ continue;
+ }
+
+ auto owner = result->getNumber("owner");
+ auto newOwner = result->getNumber("new_owner");
+ uint32_t bidder = result->getNumber("bidder");
+ std::string bidderName = result->getString("bidder_name");
+ uint32_t highestBid = result->getNumber("highest_bid");
+ uint32_t internalBid = result->getNumber("internal_bid");
+ uint32_t bidEndDate = result->getNumber("bid_end_date");
+ auto state = static_cast(result->getNumber("state"));
+ auto transferStatus = result->getNumber("transfer_status");
+ const auto timeNow = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count();
+
+ // Transfer house owner
+ auto isTransferOnRestart = g_configManager().getBoolean(TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART);
+ if (isTransferOnRestart && newOwner >= 0) {
+ g_game().setTransferPlayerHouseItems(houseId, owner);
+ if (newOwner == 0) {
+ g_logger().debug("Removing house id '{}' owner", houseId);
house->setOwner(0);
- bidEndDate = 0;
} else {
- house->setOwner(owner, false);
- house->setState(state);
+ g_logger().debug("Setting house id '{}' owner to player GUID '{}'", houseId, newOwner);
+ house->setOwner(newOwner);
+ }
+ } else if (state == CyclopediaHouseState::Available && timeNow > bidEndDate && bidder > 0) {
+ g_logger().debug("[BID] - Setting house id '{}' owner to player GUID '{}'", houseId, bidder);
+ if (highestBid < internalBid) {
+ uint32_t diff = internalBid - highestBid;
+ IOLoginData::increaseBankBalance(bidder, diff);
+ }
+ house->setOwner(bidder);
+ bidder = 0;
+ bidderName = "";
+ highestBid = 0;
+ internalBid = 0;
+ bidEndDate = 0;
+ } else if (state == CyclopediaHouseState::Transfer && timeNow > bidEndDate && bidder > 0) {
+ g_logger().debug("[TRANSFER] - Removing house id '{}' from owner GUID '{}' and transfering to new owner GUID '{}'", houseId, owner, bidder);
+ if (transferStatus) {
+ house->setOwner(bidder);
+ IOLoginData::increaseBankBalance(owner, internalBid);
+ } else {
+ house->setOwner(owner);
}
- house->setBidder(bidder);
- house->setBidderName(bidderName);
- house->setHighestBid(highestBid);
- house->setInternalBid(internalBid);
- house->setBidHolderLimit(internalBid);
- house->setBidEndDate(bidEndDate);
- house->setTransferStatus(transferStatus);
+ bidder = 0;
+ bidderName = "";
+ internalBid = 0;
+ bidEndDate = 0;
+ transferStatus = false;
+ } else if (state == CyclopediaHouseState::MoveOut && timeNow > bidEndDate) {
+ g_logger().debug("[MOVE OUT] - Removing house id '{}' owner", houseId);
+ house->setOwner(0);
+ bidEndDate = 0;
+ } else {
+ house->setOwner(owner, false);
+ house->setState(state);
}
+ house->setBidder(bidder);
+ house->setBidderName(bidderName);
+ house->setHighestBid(highestBid);
+ house->setInternalBid(internalBid);
+ house->setBidHolderLimit(internalBid);
+ house->setBidEndDate(bidEndDate);
+ house->setTransferStatus(transferStatus);
} while (result->next());
result = db.storeQuery("SELECT `house_id`, `listid`, `list` FROM `house_lists`");
From c75da854fe9589b2d86f3b1c8a253eed14f34d97 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Thu, 31 Oct 2024 00:21:53 -0300
Subject: [PATCH 20/28] fix copy
---
src/game/game.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 1e2893bc371..20d11a9a155 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -10877,7 +10877,7 @@ void Game::playerCyclopediaHousesByTown(uint32_t playerId, const std::string &to
} else {
auto playerHouses = g_game().map.houses.getAllHousesByPlayerId(player->getGUID());
if (playerHouses.size()) {
- for (const auto playerHouse : playerHouses) {
+ for (const auto &playerHouse : playerHouses) {
if (!playerHouse) {
continue;
}
From 1a2934de3dc5b53ce6d4f8df5b63355c1c350483 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Thu, 31 Oct 2024 03:32:00 +0000
Subject: [PATCH 21/28] Code format - (Clang-format)
---
src/creatures/monsters/spawns/spawn_monster.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp
index 153db66dee4..7d7bbc84e34 100644
--- a/src/creatures/monsters/spawns/spawn_monster.cpp
+++ b/src/creatures/monsters/spawns/spawn_monster.cpp
@@ -327,7 +327,7 @@ void SpawnMonster::scheduleSpawn(uint32_t spawnMonsterId, spawnBlock_t &sb, cons
}
void SpawnMonster::cleanup() {
- for (auto it = spawnedMonsterMap.begin(); it != spawnedMonsterMap.end(); ) {
+ for (auto it = spawnedMonsterMap.begin(); it != spawnedMonsterMap.end();) {
const auto &monster = it->second;
if (!monster || monster->isRemoved()) {
auto spawnIt = spawnMonsterMap.find(it->first);
From 7370433f5809aba2f15230bf31290f468dd662b0 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Thu, 31 Oct 2024 00:37:17 -0300
Subject: [PATCH 22/28] fix: using enum
---
src/creatures/players/player.cpp | 51 +++++++++++++++++---------------
1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp
index 6cb69074a85..b42c3f17672 100644
--- a/src/creatures/players/player.cpp
+++ b/src/creatures/players/player.cpp
@@ -10448,103 +10448,106 @@ uint16_t Player::getPlayerVocationEnum() const {
}
BidErrorMessage Player::canBidHouse(uint32_t houseId) {
+ using enum BidErrorMessage;
const auto house = g_game().map.houses.getHouseByClientId(houseId);
if (!house) {
- return BidErrorMessage::Internal;
+ return Internal;
}
if (getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
- return BidErrorMessage::Rookgaard;
+ return Rookgaard;
}
if (!isPremium()) {
- return BidErrorMessage::Premium;
+ return Premium;
}
if (getAccount()->getHouseBidId() != 0) {
- return BidErrorMessage::OnlyOneBid;
+ return OnlyOneBid;
}
if (getBankBalance() < (house->getRent() + house->getHighestBid())) {
- return BidErrorMessage::NotEnoughMoney;
+ return NotEnoughMoney;
}
if (house->isGuildhall()) {
if (getGuildRank() && getGuildRank()->level != 3) {
- return BidErrorMessage::Guildhall;
+ return Guildhall;
}
if (getGuild() && getGuild()->getBankBalance() < (house->getRent() + house->getHighestBid())) {
- return BidErrorMessage::NotEnoughGuildMoney;
+ return NotEnoughGuildMoney;
}
}
- return BidErrorMessage::NoError;
+ return NoError;
}
TransferErrorMessage Player::canTransferHouse(uint32_t houseId, uint32_t newOwnerGUID) {
+ using enum TransferErrorMessage;
const auto house = g_game().map.houses.getHouseByClientId(houseId);
if (!house) {
- return TransferErrorMessage::Internal;
+ return Internal;
}
if (getGUID() != house->getOwner()) {
- return TransferErrorMessage::NotHouseOwner;
+ return NotHouseOwner;
}
if (getGUID() == newOwnerGUID) {
- return TransferErrorMessage::AlreadyTheOwner;
+ return AlreadyTheOwner;
}
const auto newOwner = g_game().getPlayerByGUID(newOwnerGUID, true);
if (!newOwner) {
- return TransferErrorMessage::CharacterNotExist;
+ return CharacterNotExist;
}
if (newOwner->getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
- return TransferErrorMessage::Rookgaard;
+ return Rookgaard;
}
if (!newOwner->isPremium()) {
- return TransferErrorMessage::Premium;
+ return Premium;
}
if (newOwner->getAccount()->getHouseBidId() != 0) {
- return TransferErrorMessage::OnlyOneBid;
+ return OnlyOneBid;
}
- return TransferErrorMessage::Success;
+ return Success;
}
AcceptTransferErrorMessage Player::canAcceptTransferHouse(uint32_t houseId) {
+ using enum AcceptTransferErrorMessage;
const auto house = g_game().map.houses.getHouseByClientId(houseId);
if (!house) {
- return AcceptTransferErrorMessage::Internal;
+ return Internal;
}
if (getGUID() != house->getBidder()) {
- return AcceptTransferErrorMessage::NotNewOwner;
+ return NotNewOwner;
}
if (!isPremium()) {
- return AcceptTransferErrorMessage::Premium;
+ return Premium;
}
if (getAccount()->getHouseBidId() != 0) {
- return AcceptTransferErrorMessage::AlreadyBid;
+ return AlreadyBid;
}
if (getPlayerVocationEnum() == Vocation_t::VOCATION_NONE) {
- return AcceptTransferErrorMessage::Rookgaard;
+ return Rookgaard;
}
if (getBankBalance() < (house->getRent() + house->getInternalBid())) {
- return AcceptTransferErrorMessage::Frozen;
+ return Frozen;
}
if (house->getTransferStatus()) {
- return AcceptTransferErrorMessage::AlreadyAccepted;
+ return AlreadyAccepted;
}
- return AcceptTransferErrorMessage::Success;
+ return Success;
}
From 0fe8b2d161124a045fa1025c91556695f0032f77 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Thu, 31 Oct 2024 00:42:18 -0300
Subject: [PATCH 23/28] fix: remove items from house when removing owner
---
src/io/iomapserialize.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp
index c54f39f99b4..1479197c2c5 100644
--- a/src/io/iomapserialize.cpp
+++ b/src/io/iomapserialize.cpp
@@ -322,6 +322,7 @@ bool IOMapSerialize::loadHouseInfo() {
} else if (state == CyclopediaHouseState::Transfer && timeNow > bidEndDate && bidder > 0) {
g_logger().debug("[TRANSFER] - Removing house id '{}' from owner GUID '{}' and transfering to new owner GUID '{}'", houseId, owner, bidder);
if (transferStatus) {
+ g_game().setTransferPlayerHouseItems(houseId, owner);
house->setOwner(bidder);
IOLoginData::increaseBankBalance(owner, internalBid);
} else {
@@ -334,6 +335,7 @@ bool IOMapSerialize::loadHouseInfo() {
transferStatus = false;
} else if (state == CyclopediaHouseState::MoveOut && timeNow > bidEndDate) {
g_logger().debug("[MOVE OUT] - Removing house id '{}' owner", houseId);
+ g_game().setTransferPlayerHouseItems(houseId, owner);
house->setOwner(0);
bidEndDate = 0;
} else {
From e2e9ddf1f0ff8fa7ef9cbadaab604df4fa740241 Mon Sep 17 00:00:00 2001
From: Pedro Henrique Alves Cruz
Date: Mon, 18 Nov 2024 22:01:25 -0300
Subject: [PATCH 24/28] fix: reversed houseBidId with accountId on db query
---
src/account/account_repository_db.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/account/account_repository_db.cpp b/src/account/account_repository_db.cpp
index 7674a8a08f4..b2e8fd80754 100644
--- a/src/account/account_repository_db.cpp
+++ b/src/account/account_repository_db.cpp
@@ -53,8 +53,8 @@ bool AccountRepositoryDB::save(const std::unique_ptr &accInfo) {
accInfo->premiumLastDay,
accInfo->creationTime,
accInfo->premiumDaysPurchased,
- accInfo->id,
- accInfo->houseBidId
+ accInfo->houseBidId,
+ accInfo->id
)
);
From c36436dd6b0604cbb24cd51d41d14fb4f67be814 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Mon, 9 Dec 2024 20:22:42 +0000
Subject: [PATCH 25/28] Lua code format - (Stylua)
---
data-otservbr-global/migrations/46.lua | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/data-otservbr-global/migrations/46.lua b/data-otservbr-global/migrations/46.lua
index e1de9f7e8f8..506da3a132b 100644
--- a/data-otservbr-global/migrations/46.lua
+++ b/data-otservbr-global/migrations/46.lua
@@ -4,4 +4,4 @@ function onUpdateDatabase()
db.query("ALTER TABLE `players` MODIFY `conditions` mediumblob NOT NULL;")
return true
-end
\ No newline at end of file
+end
From b4dc46bf1b345a1dc9597ecd64d7bec5a9eea9f8 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Mon, 9 Dec 2024 17:24:12 -0300
Subject: [PATCH 26/28] fix: files removed by resolving conflicts
---
data-otservbr-global/migrations/47.lua | 28 +++++++++++++++++++++++++-
data-otservbr-global/migrations/48.lua | 3 +++
schema.sql | 2 +-
3 files changed, 31 insertions(+), 2 deletions(-)
create mode 100644 data-otservbr-global/migrations/48.lua
diff --git a/data-otservbr-global/migrations/47.lua b/data-otservbr-global/migrations/47.lua
index 86a6d8ffec1..3fcf70a40c2 100644
--- a/data-otservbr-global/migrations/47.lua
+++ b/data-otservbr-global/migrations/47.lua
@@ -1,3 +1,29 @@
function onUpdateDatabase()
- return false -- true = There are others migrations file | false = this is the last migration file
+ logger.info("Updating database to version 48 (House Auction)")
+
+ db.query([[
+ ALTER TABLE `houses`
+ DROP `bid`,
+ DROP `bid_end`,
+ DROP `last_bid`,
+ DROP `highest_bidder`
+ ]])
+
+ db.query([[
+ ALTER TABLE `houses`
+ ADD `bidder` int(11) NOT NULL DEFAULT '0',
+ ADD `bidder_name` varchar(255) NOT NULL DEFAULT '',
+ ADD `highest_bid` int(11) NOT NULL DEFAULT '0',
+ ADD `internal_bid` int(11) NOT NULL DEFAULT '0',
+ ADD `bid_end_date` int(11) NOT NULL DEFAULT '0',
+ ADD `state` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
+ ADD `transfer_status` tinyint(1) DEFAULT '0'
+ ]])
+
+ db.query([[
+ ALTER TABLE `accounts`
+ ADD `house_bid_id` int(11) NOT NULL DEFAULT '0'
+ ]])
+
+ return true
end
diff --git a/data-otservbr-global/migrations/48.lua b/data-otservbr-global/migrations/48.lua
new file mode 100644
index 00000000000..86a6d8ffec1
--- /dev/null
+++ b/data-otservbr-global/migrations/48.lua
@@ -0,0 +1,3 @@
+function onUpdateDatabase()
+ return false -- true = There are others migrations file | false = this is the last migration file
+end
diff --git a/schema.sql b/schema.sql
index 3620f0b3668..6fe1f21cbb8 100644
--- a/schema.sql
+++ b/schema.sql
@@ -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', '47'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');
+INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '48'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0');
-- Table structure `accounts`
CREATE TABLE IF NOT EXISTS `accounts` (
From e9d6a3339f5aa25e4881bd7a8c4a7120ef7a5ac7 Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Mon, 30 Dec 2024 23:16:06 -0300
Subject: [PATCH 27/28] fix ubuntu build
---
src/lua/functions/map/house_functions.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lua/functions/map/house_functions.cpp b/src/lua/functions/map/house_functions.cpp
index b26db1661f3..dd20d6fdcf6 100644
--- a/src/lua/functions/map/house_functions.cpp
+++ b/src/lua/functions/map/house_functions.cpp
@@ -9,6 +9,7 @@
#include "lua/functions/map/house_functions.hpp"
+#include "account/account.hpp"
#include "config/configmanager.hpp"
#include "items/bed.hpp"
#include "game/game.hpp"
From c81cf1a5d2c0b14e4b1841f7bf8e2100d0deed4e Mon Sep 17 00:00:00 2001
From: murilo09 <78226931+murilo09@users.noreply.github.com>
Date: Mon, 30 Dec 2024 23:30:12 -0300
Subject: [PATCH 28/28] fix migration version log
---
data-otservbr-global/migrations/10.lua | 2 +-
data-otservbr-global/migrations/11.lua | 2 +-
data-otservbr-global/migrations/12.lua | 2 +-
data-otservbr-global/migrations/13.lua | 2 +-
data-otservbr-global/migrations/14.lua | 2 +-
data-otservbr-global/migrations/15.lua | 2 +-
data-otservbr-global/migrations/16.lua | 2 +-
data-otservbr-global/migrations/17.lua | 2 +-
data-otservbr-global/migrations/18.lua | 2 +-
data-otservbr-global/migrations/19.lua | 2 +-
data-otservbr-global/migrations/2.lua | 2 +-
data-otservbr-global/migrations/20.lua | 2 +-
data-otservbr-global/migrations/21.lua | 2 +-
data-otservbr-global/migrations/22.lua | 2 +-
data-otservbr-global/migrations/23.lua | 2 +-
data-otservbr-global/migrations/24.lua | 2 +-
data-otservbr-global/migrations/25.lua | 2 +-
data-otservbr-global/migrations/26.lua | 2 +-
data-otservbr-global/migrations/27.lua | 2 +-
data-otservbr-global/migrations/28.lua | 2 +-
data-otservbr-global/migrations/29.lua | 2 +-
data-otservbr-global/migrations/3.lua | 2 +-
data-otservbr-global/migrations/30.lua | 2 +-
data-otservbr-global/migrations/31.lua | 2 +-
data-otservbr-global/migrations/32.lua | 2 +-
data-otservbr-global/migrations/33.lua | 2 +-
data-otservbr-global/migrations/34.lua | 2 +-
data-otservbr-global/migrations/35.lua | 2 +-
data-otservbr-global/migrations/36.lua | 2 +-
data-otservbr-global/migrations/37.lua | 2 +-
data-otservbr-global/migrations/38.lua | 2 +-
data-otservbr-global/migrations/39.lua | 2 +-
data-otservbr-global/migrations/4.lua | 2 +-
data-otservbr-global/migrations/40.lua | 2 +-
data-otservbr-global/migrations/41.lua | 2 +-
data-otservbr-global/migrations/42.lua | 2 +-
data-otservbr-global/migrations/43.lua | 2 +-
data-otservbr-global/migrations/44.lua | 2 +-
data-otservbr-global/migrations/45.lua | 2 +-
data-otservbr-global/migrations/46.lua | 2 +-
data-otservbr-global/migrations/47.lua | 2 +-
data-otservbr-global/migrations/48.lua | 26 ++++++++++++-
data-otservbr-global/migrations/5.lua | 2 +-
data-otservbr-global/migrations/6.lua | 2 +-
data-otservbr-global/migrations/7.lua | 2 +-
data-otservbr-global/migrations/8.lua | 53 +++++++++++++-------------
data-otservbr-global/migrations/9.lua | 2 +-
47 files changed, 97 insertions(+), 72 deletions(-)
diff --git a/data-otservbr-global/migrations/10.lua b/data-otservbr-global/migrations/10.lua
index 9dfded3813d..adfa41bb535 100644
--- a/data-otservbr-global/migrations/10.lua
+++ b/data-otservbr-global/migrations/10.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 11 (Guilds Balance)")
+ logger.info("Updating database to version 10 (Guilds Balance)")
db.query("ALTER TABLE `guilds` ADD `balance` bigint(20) UNSIGNED NOT NULL DEFAULT '0';")
end
diff --git a/data-otservbr-global/migrations/11.lua b/data-otservbr-global/migrations/11.lua
index 08d40b66381..a10d3d2980c 100644
--- a/data-otservbr-global/migrations/11.lua
+++ b/data-otservbr-global/migrations/11.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 12 (Player get daily reward)")
+ logger.info("Updating database to version 11 (Player get daily reward)")
db.query("ALTER TABLE `players` ADD `isreward` tinyint(1) NOT NULL DEFAULT 1")
end
diff --git a/data-otservbr-global/migrations/12.lua b/data-otservbr-global/migrations/12.lua
index e83ca4e51f8..20a2afc4582 100644
--- a/data-otservbr-global/migrations/12.lua
+++ b/data-otservbr-global/migrations/12.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 13 (Boosted Creature Outfit)")
+ logger.info("Updating database to version 12 (Boosted Creature Outfit)")
db.query("ALTER TABLE boosted_creature ADD `looktype` int(11) NOT NULL DEFAULT 136;")
db.query("ALTER TABLE boosted_creature ADD `lookfeet` int(11) NOT NULL DEFAULT 0;")
db.query("ALTER TABLE boosted_creature ADD `looklegs` int(11) NOT NULL DEFAULT 0;")
diff --git a/data-otservbr-global/migrations/13.lua b/data-otservbr-global/migrations/13.lua
index 479b28eda79..4747efdcb96 100644
--- a/data-otservbr-global/migrations/13.lua
+++ b/data-otservbr-global/migrations/13.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 14 (Fixed mana spent)")
+ logger.info("Updating database to version 13 (Fixed mana spent)")
db.query("ALTER TABLE `players` CHANGE `manaspent` `manaspent` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0';")
end
diff --git a/data-otservbr-global/migrations/14.lua b/data-otservbr-global/migrations/14.lua
index 7c23d8053b5..281eb40722a 100644
--- a/data-otservbr-global/migrations/14.lua
+++ b/data-otservbr-global/migrations/14.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 15 (Magic Shield Spell)")
+ logger.info("Updating database to version 14 (Magic Shield Spell)")
db.query("ALTER TABLE `players` ADD `manashield` SMALLINT UNSIGNED NOT NULL DEFAULT '0' AFTER `skill_manaleech_amount`")
db.query("ALTER TABLE `players` ADD `max_manashield` SMALLINT UNSIGNED NOT NULL DEFAULT '0' AFTER `manashield`")
end
diff --git a/data-otservbr-global/migrations/15.lua b/data-otservbr-global/migrations/15.lua
index 73daf3c5b31..2c4a37ba315 100644
--- a/data-otservbr-global/migrations/15.lua
+++ b/data-otservbr-global/migrations/15.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 16 (Rook sample and GOD player values)")
+ logger.info("Updating database to version 15 (Rook sample and GOD player values)")
-- Rook Sample
db.query("UPDATE `players` SET `maglevel` = 2, `manaspent` = 5936, `skill_club` = 12, `skill_club_tries` = 155, `skill_sword` = 12, `skill_sword_tries` = 155, `skill_axe` = 12, `skill_axe_tries` = 155, `skill_dist` = 12, `skill_dist_tries` = 93 WHERE `id` = 1;")
-- GOD
diff --git a/data-otservbr-global/migrations/16.lua b/data-otservbr-global/migrations/16.lua
index a5766130bc3..027f2fe9822 100644
--- a/data-otservbr-global/migrations/16.lua
+++ b/data-otservbr-global/migrations/16.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- print("Updating database to version 17 (Tutorial support)")
+ print("Updating database to version 16 (Tutorial support)")
db.query("ALTER TABLE `players` ADD `istutorial` SMALLINT(1) NOT NULL DEFAULT '0'")
end
diff --git a/data-otservbr-global/migrations/17.lua b/data-otservbr-global/migrations/17.lua
index 9d5f0d8d624..c84d6ec8ea6 100644
--- a/data-otservbr-global/migrations/17.lua
+++ b/data-otservbr-global/migrations/17.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 18 (Fix guild creation myaac)")
+ logger.info("Updating database to version 17 (Fix guild creation myaac)")
db.query("ALTER TABLE `guilds` ADD `level` int(11) NOT NULL DEFAULT 1")
db.query("ALTER TABLE `guilds` ADD `points` int(11) NOT NULL DEFAULT 0")
end
diff --git a/data-otservbr-global/migrations/18.lua b/data-otservbr-global/migrations/18.lua
index e017b86e05b..0f5777a2678 100644
--- a/data-otservbr-global/migrations/18.lua
+++ b/data-otservbr-global/migrations/18.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 19 (Prey system rework + Task hunting system)")
+ logger.info("Updating database to version 18 (Prey system rework + Task hunting system)")
db.query([[
ALTER TABLE `players`
DROP `prey_stamina_1`,
diff --git a/data-otservbr-global/migrations/19.lua b/data-otservbr-global/migrations/19.lua
index e7d27a859ef..dd0c82d075f 100644
--- a/data-otservbr-global/migrations/19.lua
+++ b/data-otservbr-global/migrations/19.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 20 (Gamestore accepting Tournament Coins)")
+ logger.info("Updating database to version 19 (Gamestore accepting Tournament Coins)")
db.query("ALTER TABLE `accounts` ADD `tournament_coins` int(11) NOT NULL DEFAULT 0 AFTER `coins`")
db.query("ALTER TABLE `store_history` ADD `coin_type` tinyint(1) NOT NULL DEFAULT 0 AFTER `description`")
diff --git a/data-otservbr-global/migrations/2.lua b/data-otservbr-global/migrations/2.lua
index 72c797b4b0e..b5674fecacc 100644
--- a/data-otservbr-global/migrations/2.lua
+++ b/data-otservbr-global/migrations/2.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 3 (account refactor)")
+ logger.info("Updating database to version 2 (account refactor)")
db.query([[
LOCK TABLES
diff --git a/data-otservbr-global/migrations/20.lua b/data-otservbr-global/migrations/20.lua
index daaefc6f041..f232bf2a7e8 100644
--- a/data-otservbr-global/migrations/20.lua
+++ b/data-otservbr-global/migrations/20.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 21 (Fix market price size)")
+ logger.info("Updating database to version 20 (Fix market price size)")
db.query("ALTER TABLE `market_history` CHANGE `price` `price` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0';")
db.query("ALTER TABLE `market_offers` CHANGE `price` `price` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0';")
end
diff --git a/data-otservbr-global/migrations/21.lua b/data-otservbr-global/migrations/21.lua
index cec635ed937..5c9e1a0ec8e 100644
--- a/data-otservbr-global/migrations/21.lua
+++ b/data-otservbr-global/migrations/21.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 22 (forge and tier system)")
+ logger.info("Updating database to version 21 (forge and tier system)")
db.query("ALTER TABLE `market_offers` ADD `tier` tinyint UNSIGNED NOT NULL DEFAULT '0';")
db.query("ALTER TABLE `market_history` ADD `tier` tinyint UNSIGNED NOT NULL DEFAULT '0';")
db.query("ALTER TABLE `players` ADD `forge_dusts` bigint(21) NOT NULL DEFAULT '0';")
diff --git a/data-otservbr-global/migrations/22.lua b/data-otservbr-global/migrations/22.lua
index c4c5bd385bc..9a2a4475a4b 100644
--- a/data-otservbr-global/migrations/22.lua
+++ b/data-otservbr-global/migrations/22.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 23 (fix offline training skill size)")
+ logger.info("Updating database to version 22 (fix offline training skill size)")
db.query([[
ALTER TABLE `players`
MODIFY offlinetraining_skill tinyint(2) NOT NULL DEFAULT '-1';
diff --git a/data-otservbr-global/migrations/23.lua b/data-otservbr-global/migrations/23.lua
index 8edac8cef47..dbf161bb474 100644
--- a/data-otservbr-global/migrations/23.lua
+++ b/data-otservbr-global/migrations/23.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 24 (forge history)")
+ logger.info("Updating database to version 23 (forge history)")
db.query([[
CREATE TABLE IF NOT EXISTS `forge_history` (
`id` int NOT NULL AUTO_INCREMENT,
diff --git a/data-otservbr-global/migrations/24.lua b/data-otservbr-global/migrations/24.lua
index fed9f189085..2d5286e5608 100644
--- a/data-otservbr-global/migrations/24.lua
+++ b/data-otservbr-global/migrations/24.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 25 (random mount outfit window)")
+ logger.info("Updating database to version 24 (random mount outfit window)")
db.query("ALTER TABLE `players` ADD `randomize_mount` SMALLINT(1) NOT NULL DEFAULT '0'")
end
diff --git a/data-otservbr-global/migrations/25.lua b/data-otservbr-global/migrations/25.lua
index 4d229bb58e5..41f83e2b72b 100644
--- a/data-otservbr-global/migrations/25.lua
+++ b/data-otservbr-global/migrations/25.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 26 (reward bag fix)")
+ logger.info("Updating database to version 25 (reward bag fix)")
db.query("UPDATE player_rewards SET pid = 0 WHERE itemtype = 19202;")
end
diff --git a/data-otservbr-global/migrations/26.lua b/data-otservbr-global/migrations/26.lua
index ddf821ca5cd..24db966339f 100644
--- a/data-otservbr-global/migrations/26.lua
+++ b/data-otservbr-global/migrations/26.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 27 (towns)")
+ logger.info("Updating database to version 26 (towns)")
db.query([[
CREATE TABLE IF NOT EXISTS `towns` (
diff --git a/data-otservbr-global/migrations/27.lua b/data-otservbr-global/migrations/27.lua
index 73e7bf5c4f7..478e6da6207 100644
--- a/data-otservbr-global/migrations/27.lua
+++ b/data-otservbr-global/migrations/27.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 28 (bosstiary system)")
+ logger.info("Updating database to version 27 (bosstiary system)")
db.query("ALTER TABLE `players` ADD `boss_points` int NOT NULL DEFAULT '0';")
db.query([[
CREATE TABLE IF NOT EXISTS `boosted_boss` (
diff --git a/data-otservbr-global/migrations/28.lua b/data-otservbr-global/migrations/28.lua
index d7575edf3c8..06adece4d49 100644
--- a/data-otservbr-global/migrations/28.lua
+++ b/data-otservbr-global/migrations/28.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 29 (transfer coins)")
+ logger.info("Updating database to version 28 (transfer coins)")
db.query("ALTER TABLE `accounts` ADD `coins_transferable` int unsigned NOT NULL DEFAULT '0';")
end
diff --git a/data-otservbr-global/migrations/29.lua b/data-otservbr-global/migrations/29.lua
index 0c633e46b5d..91834f4f2f6 100644
--- a/data-otservbr-global/migrations/29.lua
+++ b/data-otservbr-global/migrations/29.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 30 (looktypeEx)")
+ logger.info("Updating database to version 29 (looktypeEx)")
db.query("ALTER TABLE `boosted_boss` ADD `looktypeEx` int unsigned NOT NULL DEFAULT '0';")
end
diff --git a/data-otservbr-global/migrations/3.lua b/data-otservbr-global/migrations/3.lua
index ae06343be07..0a1aec6f6df 100644
--- a/data-otservbr-global/migrations/3.lua
+++ b/data-otservbr-global/migrations/3.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 4 (prey tick)")
+ logger.info("Updating database to version 3 (prey tick)")
db.query([[
ALTER TABLE `prey_slots`
diff --git a/data-otservbr-global/migrations/30.lua b/data-otservbr-global/migrations/30.lua
index 4ee1632421d..4749f1588ac 100644
--- a/data-otservbr-global/migrations/30.lua
+++ b/data-otservbr-global/migrations/30.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 31 (loyalty)")
+ logger.info("Updating database to version 30 (loyalty)")
db.query([[
ALTER TABLE `accounts` ADD COLUMN `premdays_purchased` int(11) NOT NULL DEFAULT 0;
]])
diff --git a/data-otservbr-global/migrations/31.lua b/data-otservbr-global/migrations/31.lua
index 5ba21bbe561..9659f296ac5 100644
--- a/data-otservbr-global/migrations/31.lua
+++ b/data-otservbr-global/migrations/31.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 32 (account_sessions)")
+ logger.info("Updating database to version 31 (account_sessions)")
db.query([[
CREATE TABLE IF NOT EXISTS `account_sessions` (
`id` VARCHAR(191) NOT NULL,
diff --git a/data-otservbr-global/migrations/32.lua b/data-otservbr-global/migrations/32.lua
index 078ef407da6..c90de61886b 100644
--- a/data-otservbr-global/migrations/32.lua
+++ b/data-otservbr-global/migrations/32.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 33 (wheel of destiny)")
+ logger.info("Updating database to version 32 (wheel of destiny)")
db.query([[
CREATE TABLE IF NOT EXISTS `player_wheeldata` (
`player_id` int(11) NOT NULL,
diff --git a/data-otservbr-global/migrations/33.lua b/data-otservbr-global/migrations/33.lua
index 2c77cbb6e24..7c0852a32bc 100644
--- a/data-otservbr-global/migrations/33.lua
+++ b/data-otservbr-global/migrations/33.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 34 (add primary keys)")
+ logger.info("Updating database to version 33 (add primary keys)")
db.query([[
ALTER TABLE `player_prey`
ADD PRIMARY KEY (`player_id`, `slot`);
diff --git a/data-otservbr-global/migrations/34.lua b/data-otservbr-global/migrations/34.lua
index 7537f6e6582..c344eae6b8d 100644
--- a/data-otservbr-global/migrations/34.lua
+++ b/data-otservbr-global/migrations/34.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 35 (bosstiary tracker)")
+ logger.info("Updating database to version 34 (bosstiary tracker)")
db.query("ALTER TABLE `player_bosstiary` ADD `tracker` blob NOT NULL;")
end
diff --git a/data-otservbr-global/migrations/35.lua b/data-otservbr-global/migrations/35.lua
index 70c820c32fd..9e2ab4dd1ba 100644
--- a/data-otservbr-global/migrations/35.lua
+++ b/data-otservbr-global/migrations/35.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 36 (fix account premdays and lastday)")
+ logger.info("Updating database to version 35 (fix account premdays and lastday)")
local resultQuery = db.storeQuery("SELECT `id`, `premdays`, `lastday` FROM `accounts` WHERE (`premdays` > 0 OR `lastday` > 0) AND `lastday` <= " .. os.time())
if resultQuery ~= false then
diff --git a/data-otservbr-global/migrations/36.lua b/data-otservbr-global/migrations/36.lua
index 5f912763cc8..5fab551e4c0 100644
--- a/data-otservbr-global/migrations/36.lua
+++ b/data-otservbr-global/migrations/36.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 37 (add coin_type to accounts)")
+ logger.info("Updating database to version 36 (add coin_type to accounts)")
db.query("ALTER TABLE `coins_transactions` ADD `coin_type` tinyint(1) UNSIGNED NOT NULL DEFAULT '1';")
end
diff --git a/data-otservbr-global/migrations/37.lua b/data-otservbr-global/migrations/37.lua
index ae3dbefbc27..7219dfbbac2 100644
--- a/data-otservbr-global/migrations/37.lua
+++ b/data-otservbr-global/migrations/37.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 38 (add pronoun to players)")
+ logger.info("Updating database to version 37 (add pronoun to players)")
db.query("ALTER TABLE `players` ADD `pronoun` int(11) NOT NULL DEFAULT '0';")
end
diff --git a/data-otservbr-global/migrations/38.lua b/data-otservbr-global/migrations/38.lua
index 3412e4d488f..7e9e3748175 100644
--- a/data-otservbr-global/migrations/38.lua
+++ b/data-otservbr-global/migrations/38.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 39 (create kv store)")
+ logger.info("Updating database to version 38 (create kv store)")
db.query([[
CREATE TABLE IF NOT EXISTS `kv_store` (
`key_name` varchar(191) NOT NULL,
diff --git a/data-otservbr-global/migrations/39.lua b/data-otservbr-global/migrations/39.lua
index 181994882db..f660e98eb37 100644
--- a/data-otservbr-global/migrations/39.lua
+++ b/data-otservbr-global/migrations/39.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 40 (house transfer ownership on startup)")
+ logger.info("Updating database to version 39 (house transfer ownership on startup)")
db.query("ALTER TABLE `houses` ADD `new_owner` int(11) NOT NULL DEFAULT '-1';")
end
diff --git a/data-otservbr-global/migrations/4.lua b/data-otservbr-global/migrations/4.lua
index 891bc20915a..a7b04453374 100644
--- a/data-otservbr-global/migrations/4.lua
+++ b/data-otservbr-global/migrations/4.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 5 (boosted creature)")
+ logger.info("Updating database to version 4 (boosted creature)")
db.query([[CREATE TABLE IF NOT EXISTS `boosted_creature` (
`boostname` TEXT,
`date` varchar(250) NOT NULL DEFAULT '',
diff --git a/data-otservbr-global/migrations/40.lua b/data-otservbr-global/migrations/40.lua
index be8794e7b25..a7d3ae6afc2 100644
--- a/data-otservbr-global/migrations/40.lua
+++ b/data-otservbr-global/migrations/40.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 41 (optimize house_lists)")
+ logger.info("Updating database to version 40 (optimize house_lists)")
db.query([[
ALTER TABLE `house_lists`
diff --git a/data-otservbr-global/migrations/41.lua b/data-otservbr-global/migrations/41.lua
index 1fa9a40e36d..504bd950073 100644
--- a/data-otservbr-global/migrations/41.lua
+++ b/data-otservbr-global/migrations/41.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 42 (fix xpboost types)")
+ logger.info("Updating database to version 41 (fix xpboost types)")
db.query([[
ALTER TABLE `players`
diff --git a/data-otservbr-global/migrations/42.lua b/data-otservbr-global/migrations/42.lua
index 4b0b97b9987..6bc750efa66 100644
--- a/data-otservbr-global/migrations/42.lua
+++ b/data-otservbr-global/migrations/42.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 43 (fix guildwar_kills_unique)")
+ logger.info("Updating database to version 42 (fix guildwar_kills_unique)")
db.query([[
ALTER TABLE `guildwar_kills`
diff --git a/data-otservbr-global/migrations/43.lua b/data-otservbr-global/migrations/43.lua
index 438ba91b713..bcf1658864d 100644
--- a/data-otservbr-global/migrations/43.lua
+++ b/data-otservbr-global/migrations/43.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 44 (feat frags_limit, payment and duration_days in guild wars)")
+ logger.info("Updating database to version 43 (feat frags_limit, payment and duration_days in guild wars)")
db.query([[
ALTER TABLE `guild_wars`
diff --git a/data-otservbr-global/migrations/44.lua b/data-otservbr-global/migrations/44.lua
index 0e2140c3183..acef11ceed9 100644
--- a/data-otservbr-global/migrations/44.lua
+++ b/data-otservbr-global/migrations/44.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 45 (fix: mana shield column size for more than 65k)")
+ logger.info("Updating database to version 44 (fix: mana shield column size for more than 65k)")
db.query([[
ALTER TABLE `players`
diff --git a/data-otservbr-global/migrations/45.lua b/data-otservbr-global/migrations/45.lua
index a88de886861..abed3464072 100644
--- a/data-otservbr-global/migrations/45.lua
+++ b/data-otservbr-global/migrations/45.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 46 (feat: vip groups)")
+ logger.info("Updating database to version 45 (feat: vip groups)")
db.query([[
CREATE TABLE IF NOT EXISTS `account_vipgroups` (
diff --git a/data-otservbr-global/migrations/46.lua b/data-otservbr-global/migrations/46.lua
index da4ade8cbf3..d7f24765b8a 100644
--- a/data-otservbr-global/migrations/46.lua
+++ b/data-otservbr-global/migrations/46.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 47 (fix: creature speed and conditions)")
+ logger.info("Updating database to version 46 (fix: creature speed and conditions)")
db.query("ALTER TABLE `players` MODIFY `conditions` mediumblob NOT NULL;")
end
diff --git a/data-otservbr-global/migrations/47.lua b/data-otservbr-global/migrations/47.lua
index 3c8908b5641..6b658e4085f 100644
--- a/data-otservbr-global/migrations/47.lua
+++ b/data-otservbr-global/migrations/47.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 46 (hireling)")
+ logger.info("Updating database to version 47 (hireling)")
db.query([[
CREATE TABLE IF NOT EXISTS `player_hirelings` (
diff --git a/data-otservbr-global/migrations/48.lua b/data-otservbr-global/migrations/48.lua
index 86a6d8ffec1..53d6ba3a948 100644
--- a/data-otservbr-global/migrations/48.lua
+++ b/data-otservbr-global/migrations/48.lua
@@ -1,3 +1,27 @@
function onUpdateDatabase()
- return false -- true = There are others migrations file | false = this is the last migration file
+ logger.info("Updating database to version 48 (House Auction)")
+
+ db.query([[
+ ALTER TABLE `houses`
+ DROP `bid`,
+ DROP `bid_end`,
+ DROP `last_bid`,
+ DROP `highest_bidder`
+ ]])
+
+ db.query([[
+ ALTER TABLE `houses`
+ ADD `bidder` int(11) NOT NULL DEFAULT '0',
+ ADD `bidder_name` varchar(255) NOT NULL DEFAULT '',
+ ADD `highest_bid` int(11) NOT NULL DEFAULT '0',
+ ADD `internal_bid` int(11) NOT NULL DEFAULT '0',
+ ADD `bid_end_date` int(11) NOT NULL DEFAULT '0',
+ ADD `state` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
+ ADD `transfer_status` tinyint(1) DEFAULT '0'
+ ]])
+
+ db.query([[
+ ALTER TABLE `accounts`
+ ADD `house_bid_id` int(11) NOT NULL DEFAULT '0'
+ ]])
end
diff --git a/data-otservbr-global/migrations/5.lua b/data-otservbr-global/migrations/5.lua
index dbc324198dd..4b027c20085 100644
--- a/data-otservbr-global/migrations/5.lua
+++ b/data-otservbr-global/migrations/5.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 6 (quickloot)")
+ logger.info("Updating database to version 5 (quickloot)")
db.query("ALTER TABLE `players` ADD `quickloot_fallback` TINYINT DEFAULT 0")
end
diff --git a/data-otservbr-global/migrations/6.lua b/data-otservbr-global/migrations/6.lua
index 91766a68ca7..cc3a3f76423 100644
--- a/data-otservbr-global/migrations/6.lua
+++ b/data-otservbr-global/migrations/6.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 7 (Stash supply)")
+ logger.info("Updating database to version 6 (Stash supply)")
db.query([[CREATE TABLE IF NOT EXISTS `player_stash` (
`player_id` INT(16) NOT NULL,
`item_id` INT(16) NOT NULL,
diff --git a/data-otservbr-global/migrations/7.lua b/data-otservbr-global/migrations/7.lua
index cade1faae1f..0666d7cf9d8 100644
--- a/data-otservbr-global/migrations/7.lua
+++ b/data-otservbr-global/migrations/7.lua
@@ -1,4 +1,4 @@
function onUpdateDatabase()
- logger.info("Updating database to version 8 (recruiter system)")
+ logger.info("Updating database to version 7 (recruiter system)")
db.query("ALTER TABLE `accounts` ADD `recruiter` INT(6) DEFAULT 0")
end
diff --git a/data-otservbr-global/migrations/8.lua b/data-otservbr-global/migrations/8.lua
index 523b705c0c7..a96db82e278 100644
--- a/data-otservbr-global/migrations/8.lua
+++ b/data-otservbr-global/migrations/8.lua
@@ -1,29 +1,30 @@
function onUpdateDatabase()
- logger.info("Updating database to version 9 (Bestiary cpp)")
+ logger.info("Updating database to version 8 (Bestiary cpp)")
db.query([[CREATE TABLE IF NOT EXISTS `player_charms` (
-`player_guid` INT(250) NOT NULL ,
-`charm_points` VARCHAR(250) NULL ,
-`charm_expansion` BOOLEAN NULL ,
-`rune_wound` INT(250) NULL ,
-`rune_enflame` INT(250) NULL ,
-`rune_poison` INT(250) NULL ,
-`rune_freeze` INT(250) NULL ,
-`rune_zap` INT(250) NULL ,
-`rune_curse` INT(250) NULL ,
-`rune_cripple` INT(250) NULL ,
-`rune_parry` INT(250) NULL ,
-`rune_dodge` INT(250) NULL ,
-`rune_adrenaline` INT(250) NULL ,
-`rune_numb` INT(250) NULL,
-`rune_cleanse` INT(250) NULL ,
-`rune_bless` INT(250) NULL ,
-`rune_scavenge` INT(250) NULL ,
-`rune_gut` INT(250) NULL ,
-`rune_low_blow` INT(250) NULL ,
-`rune_divine` INT(250) NULL ,
-`rune_vamp` INT(250) NULL ,
-`rune_void` INT(250) NULL ,
-`UsedRunesBit` VARCHAR(250) NULL ,
-`UnlockedRunesBit` VARCHAR(250) NULL,
-`tracker list` BLOB NULL ) ENGINE = InnoDB DEFAULT CHARSET=utf8;]])
+ `player_guid` INT(250) NOT NULL ,
+ `charm_points` VARCHAR(250) NULL ,
+ `charm_expansion` BOOLEAN NULL ,
+ `rune_wound` INT(250) NULL ,
+ `rune_enflame` INT(250) NULL ,
+ `rune_poison` INT(250) NULL ,
+ `rune_freeze` INT(250) NULL ,
+ `rune_zap` INT(250) NULL ,
+ `rune_curse` INT(250) NULL ,
+ `rune_cripple` INT(250) NULL ,
+ `rune_parry` INT(250) NULL ,
+ `rune_dodge` INT(250) NULL ,
+ `rune_adrenaline` INT(250) NULL ,
+ `rune_numb` INT(250) NULL,
+ `rune_cleanse` INT(250) NULL ,
+ `rune_bless` INT(250) NULL ,
+ `rune_scavenge` INT(250) NULL ,
+ `rune_gut` INT(250) NULL ,
+ `rune_low_blow` INT(250) NULL ,
+ `rune_divine` INT(250) NULL ,
+ `rune_vamp` INT(250) NULL ,
+ `rune_void` INT(250) NULL ,
+ `UsedRunesBit` VARCHAR(250) NULL ,
+ `UnlockedRunesBit` VARCHAR(250) NULL,
+ `tracker list` BLOB NULL ) ENGINE = InnoDB DEFAULT CHARSET=utf8;
+ ]])
end
diff --git a/data-otservbr-global/migrations/9.lua b/data-otservbr-global/migrations/9.lua
index 7ce8e189768..23516833fbb 100644
--- a/data-otservbr-global/migrations/9.lua
+++ b/data-otservbr-global/migrations/9.lua
@@ -1,5 +1,5 @@
function onUpdateDatabase()
- logger.info("Updating database to version 10 (Mount Colors and familiars)")
+ logger.info("Updating database to version 9 (Mount Colors and familiars)")
db.query("ALTER TABLE `players` ADD `lookmountbody` tinyint(3) unsigned NOT NULL DEFAULT '0'")
db.query("ALTER TABLE `players` ADD `lookmountfeet` tinyint(3) unsigned NOT NULL DEFAULT '0'")
db.query("ALTER TABLE `players` ADD `lookmounthead` tinyint(3) unsigned NOT NULL DEFAULT '0'")