Skip to content

Commit

Permalink
Server now checks house auctions at startup and sets new owner of hou…
Browse files Browse the repository at this point in the history
…se if player has won an auction
  • Loading branch information
V0RT4C committed May 15, 2019
1 parent a1dd547 commit a63f33b
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 85 deletions.
18 changes: 0 additions & 18 deletions data/globalevents/scripts/startup.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,6 @@ function onStartup()
result.free(resultId)
end

-- Check house auctions
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 ~= false then
repeat
local house = House(result.getDataInt(resultId, "id"))
if house ~= nil then
local highestBidder = result.getDataInt(resultId, "highest_bidder")
local balance = result.getDataLong(resultId, "balance")
local lastBid = result.getDataInt(resultId, "last_bid")
if balance >= lastBid then
db.query("UPDATE `players` SET `balance` = " .. (balance - lastBid) .. " WHERE `id` = " .. highestBidder)
house:setOwnerGuid(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

-- Remove murders that are more than 60 days old
local resultId = db.storeQuery("SELECT * FROM `player_murders` WHERE `date` <= " .. os.time() - 60 * 24 * 60 * 60)
Expand Down
176 changes: 110 additions & 66 deletions src/house.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "house.h"
#include "iologindata.h"
#include "iomapserialize.h"
#include "game.h"
#include "configmanager.h"
#include "bed.h"
Expand Down Expand Up @@ -638,93 +639,136 @@ bool Houses::loadHousesXML(const std::string& filename)

void Houses::payHouses(RentPeriod_t rentPeriod) const
{
if (rentPeriod == RENTPERIOD_NEVER) {
return;
}

time_t currentTime = time(nullptr);
for (const auto& it : houseMap) {
House* house = it.second;
if (house->getOwner() == 0) {
continue;
}

const uint32_t rent = house->getRent();
if (rent == 0 || house->getPaidUntil() > currentTime) {
continue;
}

const uint32_t ownerId = house->getOwner();
Town* town = g_game.map.towns.getTown(house->getTownId());
if (!town) {
continue;
if (!town) {
continue;
}

time_t currentTime = time(nullptr);
time_t paidUntil = currentTime;

switch (rentPeriod) {
case RENTPERIOD_DAILY:
paidUntil += 24 * 60 * 60;
break;
case RENTPERIOD_WEEKLY:
paidUntil += 24 * 60 * 60 * 7;
break;
case RENTPERIOD_MONTHLY:
paidUntil += 24 * 60 * 60 * 30;
break;
case RENTPERIOD_YEARLY:
paidUntil += 24 * 60 * 60 * 365;
break;
default:
break;
}

Player player(nullptr);
if (!IOLoginData::loadPlayerById(&player, ownerId)) {
// Player doesn't exist, reset house owner
house->setOwner(0);
continue;


//If no owner then check if auction has ended
if (house->getOwner() == 0) {

if (house->getBidEnd() < currentTime && house->getHighestBidder() != 0){
const uint32_t highestBidderId = house->getHighestBidder();
const uint64_t toPay = house->getRent() + house->getLastBid();

if (!IOLoginData::loadPlayerById(&player, highestBidderId)) {
// Player doesn't exist, reset house owner
house->setOwner(0);
continue;
}

//Try to draw money from player depot
if (g_game.removeMoney(player.getDepotLocker(house->getTownId(), true), toPay, FLAG_NOLIMIT)){
house->setOwner(highestBidderId);
house->setPaidUntil(paidUntil);
}else{
house->setOwner(0);
house->setBid(0);
house->setLastBid(0);
house->setBidEnd(0);
house->setHighestBidder(0);
house->setPayRentWarnings(0);
house->setPaidUntil(0);
IOMapSerialize::updateHouseAuctionInfo(house);
}

//Save updates to player
IOLoginData::savePlayer(&player);
}
}
//House has owner, check if pay rent is needed
else{

if (g_game.removeMoney(player.getDepotLocker(house->getTownId(), true), house->getRent(), FLAG_NOLIMIT)) {
time_t paidUntil = currentTime;
switch (rentPeriod) {
case RENTPERIOD_DAILY:
paidUntil += 24 * 60 * 60;
break;
case RENTPERIOD_WEEKLY:
paidUntil += 24 * 60 * 60 * 7;
break;
case RENTPERIOD_MONTHLY:
paidUntil += 24 * 60 * 60 * 30;
break;
case RENTPERIOD_YEARLY:
paidUntil += 24 * 60 * 60 * 365;
break;
default:
break;
if (rentPeriod == RENTPERIOD_NEVER) {
continue;
}

house->setPaidUntil(paidUntil);
} else {
if (house->getPayRentWarnings() < 7) {
int32_t daysLeft = 7 - house->getPayRentWarnings();
const uint32_t rent = house->getRent();
if (rent == 0 || house->getPaidUntil() > currentTime) {
continue;
}

Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED);
std::string period;
const uint32_t ownerId = house->getOwner();

switch (rentPeriod) {
case RENTPERIOD_DAILY:
period = "daily";
break;
if (!IOLoginData::loadPlayerById(&player, ownerId)) {
// Player doesn't exist, reset house owner
house->setOwner(0);
continue;
}

case RENTPERIOD_WEEKLY:
period = "weekly";
break;
if (g_game.removeMoney(player.getDepotLocker(house->getTownId(), true), house->getRent(), FLAG_NOLIMIT)) {
house->setPaidUntil(paidUntil);
} else {
if (house->getPayRentWarnings() < 7) {
int32_t daysLeft = 7 - house->getPayRentWarnings();

case RENTPERIOD_MONTHLY:
period = "monthly";
break;
Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED);
std::string period;

case RENTPERIOD_YEARLY:
period = "annual";
break;
switch (rentPeriod) {
case RENTPERIOD_DAILY:
period = "daily";
break;

default:
break;
}
case RENTPERIOD_WEEKLY:
period = "weekly";
break;

std::ostringstream ss;
ss << "Warning! \nThe " << period << " rent of " << house->getRent() << " gold for your house \"" << house->getName() << "\" is payable. Have it within " << daysLeft << " days or you will lose this house.";
letter->setText(ss.str());
g_game.internalAddItem(player.getDepotLocker(house->getTownId(), true), letter, INDEX_WHEREEVER, FLAG_NOLIMIT);
house->setPayRentWarnings(house->getPayRentWarnings() + 1);
} else {
house->setOwner(0, true, &player);
case RENTPERIOD_MONTHLY:
period = "monthly";
break;

case RENTPERIOD_YEARLY:
period = "annual";
break;

default:
break;
}

std::ostringstream ss;
ss << "Warning! \nThe " << period << " rent of " << house->getRent() << " gold for your house \"" << house->getName() << "\" is payable. Have it within " << daysLeft << " days or you will lose this house.";
letter->setText(ss.str());
g_game.internalAddItem(player.getDepotLocker(house->getTownId(), true), letter, INDEX_WHEREEVER, FLAG_NOLIMIT);
house->setPayRentWarnings(house->getPayRentWarnings() + 1);
} else {
house->setOwner(0, true, &player);
}
}

IOLoginData::savePlayer(&player);
}

IOLoginData::savePlayer(&player);

}

//Finally save changes to database
IOMapSerialize::saveHouseInfo();
}
36 changes: 36 additions & 0 deletions src/house.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,38 @@ class House
return rent;
}

void setBid(uint32_t bid){
this->bid = bid;
}

uint32_t getBid() const {
return bid;
}

void setLastBid(uint32_t bid){
this->lastBid = bid;
}

uint32_t getLastBid() const {
return lastBid;
}

void setHighestBidder(uint32_t highestBidder){
this->highestBidder = highestBidder;
}

uint32_t getHighestBidder() const {
return highestBidder;
}

void setBidEnd(uint32_t timestamp){
this->bidEnd = timestamp;
}

uint32_t getBidEnd() const {
return bidEnd;
}

void setPayRentWarnings(uint32_t warnings) {
rentWarnings = warnings;
}
Expand Down Expand Up @@ -249,6 +281,10 @@ class House
uint32_t rentWarnings = 0;
uint32_t rent = 0;
uint32_t townId = 0;
uint32_t bid = 0;
uint32_t bidEnd = 0;
uint32_t highestBidder = 0;
uint32_t lastBid = 0;

Position posEntry = {};

Expand Down
22 changes: 21 additions & 1 deletion src/iomapserialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "iomapserialize.h"
#include "game.h"
#include "bed.h"
#include "house.h"

extern Game g_game;

Expand Down Expand Up @@ -272,7 +273,7 @@ bool IOMapSerialize::loadHouseInfo()
{
Database* db = Database::getInstance();

DBResult_ptr result = db->storeQuery("SELECT `id`, `owner`, `paid`, `warnings` FROM `houses`");
DBResult_ptr result = db->storeQuery("SELECT `id`, `owner`, `paid`, `warnings`, `bid`, `bid_end`, `last_bid`, `highest_bidder` FROM `houses`");
if (!result) {
return false;
}
Expand All @@ -283,6 +284,10 @@ bool IOMapSerialize::loadHouseInfo()
house->setOwner(result->getNumber<uint32_t>("owner"), false);
house->setPaidUntil(result->getNumber<time_t>("paid"));
house->setPayRentWarnings(result->getNumber<uint32_t>("warnings"));
house->setBid(result->getNumber<uint32_t>("bid"));
house->setBidEnd(result->getNumber<uint32_t>("bid_end"));
house->setLastBid(result->getNumber<uint32_t>("last_bid"));
house->setHighestBidder(result->getNumber<uint32_t>("highest_bidder"));
}
} while (result->next());

Expand Down Expand Up @@ -370,3 +375,18 @@ bool IOMapSerialize::saveHouseInfo()

return transaction.commit();
}

bool IOMapSerialize::updateHouseAuctionInfo(House * house){
Database* db = Database::getInstance();
std::ostringstream query;
query << "SELECT `id` FROM `houses` WHERE `id` = " << house->getId();
DBResult_ptr result = db->storeQuery(query.str());

if(result){
query.str(std::string());
query << "UPDATE `houses` SET `owner` = " << house->getOwner() << ", `paid` = " << house->getPaidUntil() << ", `warnings` = " << house->getPayRentWarnings() << ", `bid` = " << house->getBid() << ", `bid_end` = " << house->getBidEnd() << ", `last_bid` = " << house->getLastBid() << ", `highest_bidder` = " << house->getHighestBidder() << " WHERE `id` = " << house->getId();
return db->executeQuery(query.str());
}else{
return false;
}
}
2 changes: 2 additions & 0 deletions src/iomapserialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "database.h"
#include "map.h"
#include "house.h"

class IOMapSerialize
{
Expand All @@ -30,6 +31,7 @@ class IOMapSerialize
static bool saveHouseItems();
static bool loadHouseInfo();
static bool saveHouseInfo();
static bool updateHouseAuctionInfo(House * house);

protected:
static void saveItem(PropWriteStream& stream, const Item* item);
Expand Down

0 comments on commit a63f33b

Please sign in to comment.