mirror of
https://github.com/Znote/ZnoteAAC.git
synced 2025-06-19 11:23:51 +02:00
Character Auction System
This commit is contained in:
parent
deebe044b1
commit
9c80585ef9
232
admin_auction.php
Normal file
232
admin_auction.php
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
<?php require_once 'engine/init.php'; include 'layout/overall/header.php';
|
||||||
|
protect_page();
|
||||||
|
admin_only($user_data);
|
||||||
|
$auction = $config['shop_auction'];
|
||||||
|
$step = $auction['step'];
|
||||||
|
$step_duration = $auction['step_duration'];
|
||||||
|
$loadOutfits = ($config['show_outfits']['highscores']) ? true : false;
|
||||||
|
function toDuration($is) {
|
||||||
|
$duration['day'] = $is / (24 * 60 * 60);
|
||||||
|
if (($duration['day'] - (int)$duration['day']) > 0)
|
||||||
|
$duration['hour'] = ($duration['day'] - (int)$duration['day']) * 24;
|
||||||
|
if (isset($duration['hour'])) {
|
||||||
|
if (($duration['hour'] - (int)$duration['hour']) > 0)
|
||||||
|
$duration['minute'] = ($duration['hour'] - (int)$duration['hour']) * 60;
|
||||||
|
if (isset($duration['minute'])) {
|
||||||
|
if (($duration['minute'] - (int)$duration['minute']) > 0)
|
||||||
|
$duration['second'] = ($duration['minute'] - (int)$duration['minute']) * 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tmp = array();
|
||||||
|
foreach ($duration as $type => $value) {
|
||||||
|
if ($value >= 1) {
|
||||||
|
$pluralType = ((int)$value === 1) ? $type : $type . 's';
|
||||||
|
if ($type !== 'second') $tmp[] = (int)$value . " $pluralType";
|
||||||
|
else $tmp[] = (int)$value . " $pluralType";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return implode(', ', $tmp);
|
||||||
|
}
|
||||||
|
// start
|
||||||
|
|
||||||
|
// Passive check to see if bid period has expired and someone won a deal
|
||||||
|
$time = time();
|
||||||
|
$expired_auctions = mysql_select_multi("
|
||||||
|
SELECT `id`
|
||||||
|
FROM `znote_auction_player`
|
||||||
|
WHERE `sold` = 0
|
||||||
|
AND `time_end` < {$time}
|
||||||
|
AND `bidder_account_id` > 0
|
||||||
|
");
|
||||||
|
//data_dump($expired_auctions, $this_account_id, "expired_auctions");
|
||||||
|
if ($expired_auctions !== false) {
|
||||||
|
$soldIds = array();
|
||||||
|
foreach ($expired_auctions as $a) {
|
||||||
|
$soldIds[] = $a['id'];
|
||||||
|
}
|
||||||
|
if (!empty($soldIds)) {
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_auction_player`
|
||||||
|
SET `sold`=1
|
||||||
|
WHERE `id` IN(".implode(',', $soldIds).")
|
||||||
|
LIMIT ".COUNT($soldIds).";
|
||||||
|
");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end passive check
|
||||||
|
// Pending auctions
|
||||||
|
$pending = mysql_select_multi("
|
||||||
|
SELECT
|
||||||
|
`za`.`id` AS `zaid`,
|
||||||
|
`za`.`price`,
|
||||||
|
`za`.`bid`,
|
||||||
|
`za`.`time_begin`,
|
||||||
|
`za`.`time_end`,
|
||||||
|
`p`.`id` AS `player_id`,
|
||||||
|
`p`.`name`,
|
||||||
|
`p`.`vocation`,
|
||||||
|
`p`.`level`,
|
||||||
|
`p`.`lookbody` AS `body`,
|
||||||
|
`p`.`lookfeet` AS `feet`,
|
||||||
|
`p`.`lookhead` AS `head`,
|
||||||
|
`p`.`looklegs` AS `legs`,
|
||||||
|
`p`.`looktype` AS `type`,
|
||||||
|
`p`.`lookaddons` AS `addons`
|
||||||
|
FROM `znote_auction_player` za
|
||||||
|
INNER JOIN `players` p
|
||||||
|
ON `za`.`player_id` = `p`.`id`
|
||||||
|
WHERE `p`.`account_id` = {$auction['storage_account_id']}
|
||||||
|
AND `za`.`claimed` = 0
|
||||||
|
AND `za`.`sold` = 1
|
||||||
|
ORDER BY `za`.`time_end` desc
|
||||||
|
");
|
||||||
|
// ongoing auctions
|
||||||
|
$ongoing = mysql_select_multi("
|
||||||
|
SELECT
|
||||||
|
`za`.`id` AS `zaid`,
|
||||||
|
`za`.`price`,
|
||||||
|
`za`.`bid`,
|
||||||
|
`za`.`time_begin`,
|
||||||
|
`za`.`time_end`,
|
||||||
|
`p`.`vocation`,
|
||||||
|
`p`.`level`,
|
||||||
|
`p`.`lookbody` AS `body`,
|
||||||
|
`p`.`lookfeet` AS `feet`,
|
||||||
|
`p`.`lookhead` AS `head`,
|
||||||
|
`p`.`looklegs` AS `legs`,
|
||||||
|
`p`.`looktype` AS `type`,
|
||||||
|
`p`.`lookaddons` AS `addons`
|
||||||
|
FROM `znote_auction_player` za
|
||||||
|
INNER JOIN `players` p
|
||||||
|
ON `za`.`player_id` = `p`.`id`
|
||||||
|
WHERE `p`.`account_id` = {$auction['storage_account_id']}
|
||||||
|
AND `za`.`sold` = 0
|
||||||
|
ORDER BY `za`.`time_end` desc;
|
||||||
|
");
|
||||||
|
// Completed auctions
|
||||||
|
$completed = mysql_select_multi("
|
||||||
|
SELECT
|
||||||
|
`za`.`id` AS `zaid`,
|
||||||
|
`za`.`price`,
|
||||||
|
`za`.`bid`,
|
||||||
|
`za`.`time_begin`,
|
||||||
|
`za`.`time_end`,
|
||||||
|
`p`.`id` AS `player_id`,
|
||||||
|
`p`.`name`,
|
||||||
|
`p`.`vocation`,
|
||||||
|
`p`.`level`,
|
||||||
|
`p`.`lookbody` AS `body`,
|
||||||
|
`p`.`lookfeet` AS `feet`,
|
||||||
|
`p`.`lookhead` AS `head`,
|
||||||
|
`p`.`looklegs` AS `legs`,
|
||||||
|
`p`.`looktype` AS `type`,
|
||||||
|
`p`.`lookaddons` AS `addons`
|
||||||
|
FROM `znote_auction_player` za
|
||||||
|
INNER JOIN `players` p
|
||||||
|
ON `za`.`player_id` = `p`.`id`
|
||||||
|
WHERE `za`.`claimed` = 1
|
||||||
|
ORDER BY `za`.`time_end` desc
|
||||||
|
");
|
||||||
|
?>
|
||||||
|
<h1>Character Auction History</h1>
|
||||||
|
<p><strong>Let players sell, buy and bid on characters.</strong>
|
||||||
|
<br>Creates a deeper shop economy, encourages players to spend more money in shop for points.
|
||||||
|
<br>Pay to win/progress mechanic, but also lets people who can barely afford points to gain it
|
||||||
|
<br>by leveling characters to sell. It can also discourages illegal/risky third-party account
|
||||||
|
<br>services. Since players can buy officially & support the server, dodgy competitors have to sell for cheaper.
|
||||||
|
<br>Without admin interference this is organic to each individual community economy inflation.</p>
|
||||||
|
<?php data_dump($config['shop_auction'], false, "config.php: shop_auction") ?>
|
||||||
|
<h2>Pending orders to be claimed</h2>
|
||||||
|
<?php if ($pending !== false): ?>
|
||||||
|
<table class="auction_char">
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>Player</td>
|
||||||
|
<td>Level</td>
|
||||||
|
<td>Vocation</td>
|
||||||
|
<td>Price</td>
|
||||||
|
<td>Bid</td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach($pending as $character): ?>
|
||||||
|
<tr>
|
||||||
|
<td><a href="/characterprofile.php?name=<?php echo $character['name']; ?>"><?php echo $character['name']; ?></a></td>
|
||||||
|
<td><?php echo $character['level']; ?></td>
|
||||||
|
<td><?php echo vocation_id_to_name($character['vocation']); ?></td>
|
||||||
|
<td><?php echo $character['price']; ?></td>
|
||||||
|
<td><?php echo $character['bid']; ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align: right;"><strong>Added:</strong></td>
|
||||||
|
<td><?php echo getClock($character['time_begin'], true); ?></td>
|
||||||
|
<td style="text-align: right;"><strong>Ended:</strong></td>
|
||||||
|
<td colspan="2"><?php echo getClock($character['time_end'], true); ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="yellow">
|
||||||
|
<td colspan="5"></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<h2>Ongoing auctions</h2>
|
||||||
|
<?php if (is_array($ongoing) && !empty($ongoing)): ?>
|
||||||
|
<table class="auction_char">
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>Level</td>
|
||||||
|
<td>Vocation</td>
|
||||||
|
<td>Details</td>
|
||||||
|
<td>Price</td>
|
||||||
|
<td>Bid</td>
|
||||||
|
<td>Added</td>
|
||||||
|
<td>Type</td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach($ongoing as $character): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $character['level']; ?></td>
|
||||||
|
<td><?php echo vocation_id_to_name($character['vocation']); ?></td>
|
||||||
|
<td><a href="/auctionChar.php?action=view&zaid=<?php echo $character['zaid']; ?>">VIEW</a></td>
|
||||||
|
<td><?php echo $character['price']; ?></td>
|
||||||
|
<td><?php echo $character['bid']; ?></td>
|
||||||
|
<td><?php
|
||||||
|
$ended = (time() > $character['time_end']) ? true : false;
|
||||||
|
echo getClock($character['time_begin'], true);
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<td><?php echo ($ended) ? 'Instant' : 'Bidding<br>('.toDuration(($character['time_end'] - time())).')'; ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<h2>Completed auctions</h2>
|
||||||
|
<?php
|
||||||
|
if ($completed !== false): ?>
|
||||||
|
<table class="auction_char">
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>Player</td>
|
||||||
|
<td>Level</td>
|
||||||
|
<td>Vocation</td>
|
||||||
|
<td>Price</td>
|
||||||
|
<td>Bid</td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach($completed as $character): ?>
|
||||||
|
<tr>
|
||||||
|
<td><a href="/characterprofile.php?name=<?php echo $character['name']; ?>"><?php echo $character['name']; ?></a></td>
|
||||||
|
<td><?php echo $character['level']; ?></td>
|
||||||
|
<td><?php echo vocation_id_to_name($character['vocation']); ?></td>
|
||||||
|
<td><?php echo $character['price']; ?></td>
|
||||||
|
<td><?php echo $character['bid']; ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="text-align: right;"><strong>Added:</strong></td>
|
||||||
|
<td><?php echo getClock($character['time_begin'], true); ?></td>
|
||||||
|
<td style="text-align: right;"><strong>Ended:</strong></td>
|
||||||
|
<td colspan="2"><?php echo getClock($character['time_end'], true); ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="yellow">
|
||||||
|
<td colspan="5"></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
<?php endif;
|
||||||
|
// end
|
||||||
|
include 'layout/overall/footer.php'; ?>
|
965
auctionChar.php
965
auctionChar.php
@ -1,45 +1,936 @@
|
|||||||
<?php require_once 'engine/init.php';
|
<?php require_once 'engine/init.php';
|
||||||
protect_page();
|
protect_page();
|
||||||
include 'layout/overall/header.php';
|
include 'layout/overall/header.php';
|
||||||
|
// Convert a seconds integer value into days, hours, minutes and seconds string.
|
||||||
|
function toDuration($is) {
|
||||||
|
$duration['day'] = $is / (24 * 60 * 60);
|
||||||
|
if (($duration['day'] - (int)$duration['day']) > 0)
|
||||||
|
$duration['hour'] = ($duration['day'] - (int)$duration['day']) * 24;
|
||||||
|
if (isset($duration['hour'])) {
|
||||||
|
if (($duration['hour'] - (int)$duration['hour']) > 0)
|
||||||
|
$duration['minute'] = ($duration['hour'] - (int)$duration['hour']) * 60;
|
||||||
|
if (isset($duration['minute'])) {
|
||||||
|
if (($duration['minute'] - (int)$duration['minute']) > 0)
|
||||||
|
$duration['second'] = ($duration['minute'] - (int)$duration['minute']) * 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tmp = array();
|
||||||
|
foreach ($duration as $type => $value) {
|
||||||
|
if ($value >= 1) {
|
||||||
|
$pluralType = ((int)$value === 1) ? $type : $type . 's';
|
||||||
|
if ($type !== 'second') $tmp[] = (int)$value . " $pluralType";
|
||||||
|
else $tmp[] = (int)$value . " $pluralType";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return implode(', ', $tmp);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<h1>Character auction</h1>
|
||||||
|
<?php
|
||||||
// Import from config:
|
// Import from config:
|
||||||
$auction = $config['shop_auction'];
|
$auction = $config['shop_auction'];
|
||||||
|
$loadOutfits = ($config['show_outfits']['highscores']) ? true : false;
|
||||||
|
$this_account_id = (int)$session_user_id;
|
||||||
|
$is_admin = is_admin($user_data);
|
||||||
|
|
||||||
|
// If character auction is enabled in config.php
|
||||||
if ($auction['characterAuction']) {
|
if ($auction['characterAuction']) {
|
||||||
?>
|
|
||||||
<h1>Character auctioning</h1>
|
if ($config['ServerEngine'] != 'TFS_10') {
|
||||||
<table class="auction_char">
|
echo "<p>Character shop auction system is currently only available for ServerEngine TFS_10.</p>";
|
||||||
<tr class="yellow">
|
include 'layout/overall/footer.php';
|
||||||
<td>Name</td>
|
die();
|
||||||
<td>Level</td>
|
}
|
||||||
<td>Vocation</td>
|
if ((int)$auction['storage_account_id'] === (int)$this_account_id) {
|
||||||
<td>Image</td>
|
echo "<p>The storage account cannot use the character auction.</p>";
|
||||||
<td>Price/Buy</td>
|
include 'layout/overall/footer.php';
|
||||||
</tr>
|
die();
|
||||||
<tr>
|
}
|
||||||
<td><a href="characterprofile.php?name=Tester" target="_BLANK">Tester</a></td>
|
$step = $auction['step'];
|
||||||
<td>105</td>
|
$step_duration = $auction['step_duration'];
|
||||||
<td>Sorcerer</td>
|
$actions = array(
|
||||||
<td><a href="asd" target="_BLANK">VIEW</a></td>
|
'list', // list all available players in auction
|
||||||
<td><button>105 points</button></td>
|
'view', // view a specific player
|
||||||
</tr>
|
'create', // select which character to add and initial price
|
||||||
</table>
|
'add', // add character to list
|
||||||
<textarea cols="65" rows="15">
|
'bid', // Bid or buy a specific player
|
||||||
CREATE TABLE IF NOT EXISTS `znote_auction_player` (
|
'refund', // Refund a player you added back to your account
|
||||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
'claim' // Claim a character you won through purchase or bid
|
||||||
`player_id` int(11) NOT NULL,
|
);
|
||||||
`account_id` int(11) NOT NULL,
|
|
||||||
`bidder_id` int(11) NOT NULL,
|
// Default action is list, but $_GET or $_POST will override it.
|
||||||
`vocation` int(11) NOT NULL,
|
$action = 'list';
|
||||||
`level` int(11) NOT NULL,
|
// Load selected string from actions array based on input, strict whitelist validation
|
||||||
`image` varchar(255) NOT NULL,
|
if (isset( $_GET['action']) && in_array( $_GET['action'], $actions)) {
|
||||||
`price` int(11) NOT NULL,
|
$action = $actions[array_search( $_GET['action'], $actions, true)];
|
||||||
`time` int(11) NOT NULL,
|
}
|
||||||
PRIMARY KEY (`id`)
|
if (isset($_POST['action']) && in_array($_POST['action'], $actions)) {
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
|
$action = $actions[array_search($_POST['action'], $actions, true)];
|
||||||
</textarea>
|
}
|
||||||
<?php
|
|
||||||
|
// Passive check to see if bid period has expired and someone won a deal
|
||||||
|
$time = time();
|
||||||
|
$expired_auctions = mysql_select_multi("
|
||||||
|
SELECT `id`
|
||||||
|
FROM `znote_auction_player`
|
||||||
|
WHERE `sold` = 0
|
||||||
|
AND `time_end` < {$time}
|
||||||
|
AND `bidder_account_id` > 0
|
||||||
|
");
|
||||||
|
//data_dump($expired_auctions, $this_account_id, "expired_auctions");
|
||||||
|
if ($expired_auctions !== false) {
|
||||||
|
$soldIds = array();
|
||||||
|
foreach ($expired_auctions as $a) {
|
||||||
|
$soldIds[] = $a['id'];
|
||||||
|
}
|
||||||
|
if (!empty($soldIds)) {
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_auction_player`
|
||||||
|
SET `sold`=1
|
||||||
|
WHERE `id` IN(".implode(',', $soldIds).")
|
||||||
|
LIMIT ".COUNT($soldIds).";
|
||||||
|
");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end passive check
|
||||||
|
|
||||||
|
// If we bid or buy a character
|
||||||
|
// silently continues to list if buy, back to view if bid
|
||||||
|
if ($action === 'bid') {
|
||||||
|
//data_dump($_POST, false, "Bid or buying:");
|
||||||
|
$zaid = (isset($_POST['zaid']) && (int)$_POST['zaid'] > 0) ? (int)$_POST['zaid'] : false;
|
||||||
|
$price = (isset($_POST['price']) && (int)$_POST['price'] > 0) ? (int)$_POST['price'] : false;
|
||||||
|
|
||||||
|
$action = 'list';
|
||||||
|
if ($zaid !== false && $price !== false) {
|
||||||
|
// The account of the buyer, if he can afford what he is trying to pay
|
||||||
|
$account = mysql_select_single("
|
||||||
|
SELECT
|
||||||
|
`a`.`id`,
|
||||||
|
`za`.`points`
|
||||||
|
FROM `accounts` a
|
||||||
|
INNER JOIN `znote_accounts` za
|
||||||
|
ON `a`.`id` = `za`.`account_id`
|
||||||
|
WHERE `a`.`id`= {$this_account_id}
|
||||||
|
AND `za`.`points` >= {$price}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
//data_dump($account, false, "Buyer account:");
|
||||||
|
|
||||||
|
// The character to buy, presuming it isn't sold, buyer isn't the owner, buyer can afford it
|
||||||
|
if ($account !== false) {
|
||||||
|
$character = mysql_select_single("
|
||||||
|
SELECT
|
||||||
|
`za`.`id` AS `zaid`,
|
||||||
|
`za`.`player_id`,
|
||||||
|
`za`.`original_account_id`,
|
||||||
|
`za`.`bidder_account_id`,
|
||||||
|
`za`.`time_begin`,
|
||||||
|
`za`.`time_end`,
|
||||||
|
`za`.`price`,
|
||||||
|
`za`.`bid`,
|
||||||
|
`za`.`deposit`,
|
||||||
|
`za`.`sold`
|
||||||
|
FROM `znote_auction_player` za
|
||||||
|
WHERE `za`.`id` = {$zaid}
|
||||||
|
AND `za`.`sold` = 0
|
||||||
|
AND `za`.`original_account_id` != {$this_account_id}
|
||||||
|
AND `za`.`price` <= {$price}
|
||||||
|
AND `za`.`bid`+{$step} <= {$price}
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
//data_dump($character, false, "Character to buy:");
|
||||||
|
|
||||||
|
if ($character !== false) {
|
||||||
|
// If auction already have a previous bidder, refund him his points
|
||||||
|
if ($character['bid'] > 0 && $character['bidder_account_id'] > 0) {
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_accounts`
|
||||||
|
SET `points` = `points`+{$character['bid']}
|
||||||
|
WHERE `account_id` = {$character['bidder_account_id']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// If previous bidder is not you, increase bidding period by 1 hour
|
||||||
|
// (Extending bid war to give bidding competitor a chance to retaliate)
|
||||||
|
if ((int)$character['bidder_account_id'] !== (int)$account['id']) {
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_auction_player`
|
||||||
|
SET `time_end` = `time_end`+{$step_duration}
|
||||||
|
WHERE `id` = {$character['zaid']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove points from buyer
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_accounts`
|
||||||
|
SET `points` = `points`-{$price}
|
||||||
|
WHERE `account_id` = {$account['id']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// Update auction, and set new bidder data
|
||||||
|
$time = time();
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_auction_player`
|
||||||
|
SET
|
||||||
|
`bidder_account_id` = {$account['id']},
|
||||||
|
`bid` = {$price},
|
||||||
|
`sold` = CASE WHEN {$time} >= `time_end` THEN 1 ELSE 0 END
|
||||||
|
WHERE `id` = {$character['zaid']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// If character is sold, return deposit back to sellers account
|
||||||
|
if (time() >= $character['time_end']) {
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_accounts`
|
||||||
|
SET `points` = `points`+{$character['deposit']}
|
||||||
|
WHERE `account_id` = {$account['id']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
} else {
|
||||||
|
// If character is not sold, this is a bidding war, we want to send user back to view.
|
||||||
|
$action = 'view';
|
||||||
|
}
|
||||||
|
// Note: Transferring character to the new account etc happens later in $action = 'claim'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// See a specific character in auction,
|
||||||
|
// silently fallback to list if he doesn't exist or is already sold
|
||||||
|
if ($action === 'view') { // View a character in the auction
|
||||||
|
if (!isset($zaid)) {
|
||||||
|
$zaid = (isset($_GET['zaid']) && (int)$_GET['zaid'] > 0) ? (int)$_GET['zaid'] : false;
|
||||||
|
}
|
||||||
|
if ($zaid !== false) {
|
||||||
|
// Retrieve basic character information
|
||||||
|
$character = mysql_select_single("
|
||||||
|
SELECT
|
||||||
|
`za`.`id` AS `zaid`,
|
||||||
|
`za`.`player_id`,
|
||||||
|
`za`.`original_account_id`,
|
||||||
|
`za`.`bidder_account_id`,
|
||||||
|
`za`.`time_begin`,
|
||||||
|
`za`.`time_end`,
|
||||||
|
CASE WHEN `za`.`price` > `za`.`bid`
|
||||||
|
THEN `za`.`price`
|
||||||
|
ELSE `za`.`bid`+{$step}
|
||||||
|
END AS `price`,
|
||||||
|
CASE WHEN `za`.`original_account_id` = {$this_account_id}
|
||||||
|
THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END AS `own`,
|
||||||
|
CASE WHEN `za`.`original_account_id` = {$this_account_id}
|
||||||
|
THEN `p`.`name`
|
||||||
|
ELSE ''
|
||||||
|
END AS `name`,
|
||||||
|
CASE WHEN `za`.`original_account_id` = {$this_account_id}
|
||||||
|
THEN `za`.`bid`
|
||||||
|
ELSE 0
|
||||||
|
END AS `bid`,
|
||||||
|
CASE WHEN `za`.`original_account_id` = {$this_account_id}
|
||||||
|
THEN `za`.`deposit`
|
||||||
|
ELSE 0
|
||||||
|
END AS `deposit`,
|
||||||
|
`p`.`vocation`,
|
||||||
|
`p`.`level`,
|
||||||
|
`p`.`balance`,
|
||||||
|
`p`.`lookbody` AS `body`,
|
||||||
|
`p`.`lookfeet` AS `feet`,
|
||||||
|
`p`.`lookhead` AS `head`,
|
||||||
|
`p`.`looklegs` AS `legs`,
|
||||||
|
`p`.`looktype` AS `type`,
|
||||||
|
`p`.`lookaddons` AS `addons`,
|
||||||
|
`p`.`maglevel` AS `magic`,
|
||||||
|
`p`.`skill_fist` AS `fist`,
|
||||||
|
`p`.`skill_club` AS `club`,
|
||||||
|
`p`.`skill_sword` AS `sword`,
|
||||||
|
`p`.`skill_axe` AS `axe`,
|
||||||
|
`p`.`skill_dist` AS `dist`,
|
||||||
|
`p`.`skill_shielding` AS `shielding`,
|
||||||
|
`p`.`skill_fishing` AS `fishing`
|
||||||
|
FROM `znote_auction_player` za
|
||||||
|
INNER JOIN `players` p
|
||||||
|
ON `za`.`player_id` = `p`.`id`
|
||||||
|
WHERE `za`.`id` = {$zaid}
|
||||||
|
AND `za`.`sold` = 0
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
//data_dump($character, false, "Character info");
|
||||||
|
|
||||||
|
if (is_array($character) && !empty($character)) {
|
||||||
|
// If the end of the bid is in the future, the bid is currently ongoing
|
||||||
|
$bidding_period = ((int)$character['time_end']+1 > time()) ? true : false;
|
||||||
|
$player_items = mysql_select_multi("
|
||||||
|
SELECT `itemtype`, SUM(`count`) AS `count`
|
||||||
|
FROM `player_items`
|
||||||
|
WHERE `player_id` = {$character['player_id']}
|
||||||
|
GROUP BY `itemtype`
|
||||||
|
ORDER BY MIN(`pid`) ASC
|
||||||
|
");
|
||||||
|
$depot_items = mysql_select_multi("
|
||||||
|
SELECT `itemtype`, SUM(`count`) AS `count`
|
||||||
|
FROM `player_depotitems`
|
||||||
|
WHERE `player_id` = {$character['player_id']}
|
||||||
|
GROUP BY `itemtype`
|
||||||
|
ORDER BY MIN(`pid`) ASC
|
||||||
|
");
|
||||||
|
$account = mysql_select_single("
|
||||||
|
SELECT `points`
|
||||||
|
FROM `znote_accounts`
|
||||||
|
WHERE `account_id`={$this_account_id}
|
||||||
|
AND `points` >= {$character['price']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
?>
|
||||||
|
<p>Detailed character information. <a href="/auctionChar.php?action=list">Go back to list.</a></p>
|
||||||
|
<!-- Basic info -->
|
||||||
|
<table class="auction_char">
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>Level</td>
|
||||||
|
<td>Vocation</td>
|
||||||
|
<?php if ($loadOutfits): ?>
|
||||||
|
<td>Image</td>
|
||||||
|
<?php endif; ?>
|
||||||
|
<td>Bank</td>
|
||||||
|
<td>Price</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $character['level']; ?></td>
|
||||||
|
<td><?php echo vocation_id_to_name($character['vocation']); ?></td>
|
||||||
|
<?php if ($loadOutfits): ?>
|
||||||
|
<td class="outfitColumn">
|
||||||
|
<img src="<?php echo $config['show_outfits']['imageServer']; ?>?id=<?php echo $character['type']; ?>&addons=<?php echo $character['addons']; ?>&head=<?php echo $character['head']; ?>&body=<?php echo $character['body']; ?>&legs=<?php echo $character['legs']; ?>&feet=<?php echo $character['feet']; ?>" alt="img">
|
||||||
|
</td>
|
||||||
|
<?php endif; ?>
|
||||||
|
<td><?php echo $character['balance']; ?></td>
|
||||||
|
<td><?php echo $character['price']; ?> points</td>
|
||||||
|
</tr>
|
||||||
|
<?php if ($bidding_period): ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="<?php echo ($loadOutfits) ? 5 : 4; ?>">
|
||||||
|
<p><strong>Remaining bid period:</strong> <?php echo toDuration((int)$character['time_end']-time()); ?>.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endif; ?>
|
||||||
|
</table>
|
||||||
|
<!-- Bid on character -->
|
||||||
|
<?php
|
||||||
|
if ($character['own'] == 0) {
|
||||||
|
if (is_array($account) && !empty($account)): ?>
|
||||||
|
<p>You have <strong><?php echo $account['points']; ?></strong> shop points remaining.</p>
|
||||||
|
|
||||||
|
<?php if ((int)$character['bidder_account_id'] === $this_account_id): ?>
|
||||||
|
<p><strong>So far so good!</strong>
|
||||||
|
<br>You currently have the highest bid at: <?php echo (int)$character['price']-$step; ?>
|
||||||
|
</p>
|
||||||
|
<p>If nobody bids higher than you, this character will be yours in:
|
||||||
|
<br><?php echo toDuration((int)$character['time_end']-time()); ?>.
|
||||||
|
</p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<form action="/auctionChar.php" method="POST">
|
||||||
|
<input type="hidden" name="action" value="bid">
|
||||||
|
<input type="hidden" name="zaid" value="<?php echo $character['zaid']; ?>">
|
||||||
|
<input type="number" name="price" min="<?php echo $character['price']; ?>" max="<?php echo $account['points']; ?>" step="5" value="<?php echo $character['price']; ?>" <?php if (!$bidding_period) echo 'disabled'; ?>>
|
||||||
|
<?php if (!$bidding_period): /* Because above input is disabled */ ?>
|
||||||
|
<input type="hidden" name="price" value="<?php echo $character['price']; ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<input type="submit" value="<?php echo ($bidding_period) ? 'Bid' : 'Buy'; ?>">
|
||||||
|
</form>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php if ((int)$character['bidder_account_id'] === $this_account_id): ?>
|
||||||
|
<p><strong>So far so good!</strong>
|
||||||
|
<br>You currently have the highest bid at: <?php echo (int)$character['price']-$step; ?>
|
||||||
|
</p>
|
||||||
|
<p>If nobody bids higher than you, this character will be yours in:
|
||||||
|
<br><?php echo toDuration((int)$character['time_end']-time()); ?>.
|
||||||
|
</p>
|
||||||
|
<?php else: ?>
|
||||||
|
<p>You cannot afford to buy this character.</p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endif;
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<p><strong>You are the seller of this character.</strong>
|
||||||
|
<br><strong>Name:</strong> <a href="/characterprofile.php?name=<?php echo $character['name']; ?>"><?php echo $character['name']; ?></a>
|
||||||
|
<br><strong>Price:</strong> <?php echo $character['price']; ?>
|
||||||
|
<br><strong>Bid:</strong> <?php echo $character['bid']; ?>
|
||||||
|
<br><strong>Deposit:</strong> <?php echo $character['deposit']; ?>
|
||||||
|
<?php if (!$bidding_period): ?>
|
||||||
|
<p>The bidding period has ended, you can wait until someone decides to instantly buy it, or you can reclaim your character to your account.</p>
|
||||||
|
<form action="/auctionChar.php" method="POST">
|
||||||
|
<input type="hidden" name="action" value="refund">
|
||||||
|
<input type="hidden" name="zaid" value="<?php echo $character['zaid']; ?>">
|
||||||
|
<input type="submit" value="Reclaim character back to your account">
|
||||||
|
</form>
|
||||||
|
<?php else: ?>
|
||||||
|
<p>The bidding period will last for <?php echo toDuration($character['time_end']-time()); ?>. After this period, you can reclaim your character if nobody has bid on it.</p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!-- SKILLS -->
|
||||||
|
<table class="auction_skills">
|
||||||
|
<tr class="yellow"><td colspan="4">Character skills:</td></tr>
|
||||||
|
<tr><td>magic</td><td><?php echo $character['magic']; ?></td></tr>
|
||||||
|
<tr><td>fist</td><td><?php echo $character['fist']; ?></td></tr>
|
||||||
|
<tr><td>club</td><td><?php echo $character['club']; ?></td></tr>
|
||||||
|
<tr><td>sword</td><td><?php echo $character['sword']; ?></td></tr>
|
||||||
|
<tr><td>axe</td><td><?php echo $character['axe']; ?></td></tr>
|
||||||
|
<tr><td>dist</td><td><?php echo $character['dist']; ?></td></tr>
|
||||||
|
<tr><td>shielding</td><td><?php echo $character['shielding']; ?></td></tr>
|
||||||
|
<tr><td>fishing</td><td><?php echo $character['fishing']; ?></td></tr>
|
||||||
|
</table>
|
||||||
|
<?php
|
||||||
|
$server = $config['shop']['imageServer'];
|
||||||
|
$imageType = $config['shop']['imageType'];
|
||||||
|
$items = getItemList();
|
||||||
|
?>
|
||||||
|
<!-- Player items -->
|
||||||
|
<?php if (is_array($player_items) && !empty($player_items)): ?>
|
||||||
|
<table>
|
||||||
|
<tr class="yellow">
|
||||||
|
<td colspan="3">Player items:</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>Image</td>
|
||||||
|
<td>Item</td>
|
||||||
|
<td>Count</td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach($player_items as $item): ?>
|
||||||
|
<tr>
|
||||||
|
<td><img src="<?php echo "http://".$server."/".$item['itemtype'].".".$imageType; ?>" alt="Item Image"></td>
|
||||||
|
<td><a href="/market.php?compare=<?php echo $item['itemtype']; ?>" target="_BLANK"><?php echo (isset($items[$item['itemtype']])) ? $items[$item['itemtype']] : $item['itemtype']; ?></a></td>
|
||||||
|
<td><?php echo $item['count']; ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
<?php endif; ?>
|
||||||
|
<!-- Depot items -->
|
||||||
|
<?php if (is_array($depot_items) && !empty($depot_items)): ?>
|
||||||
|
<table>
|
||||||
|
<tr class="yellow">
|
||||||
|
<td colspan="3">Depot items:</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>Image</td>
|
||||||
|
<td>Item</td>
|
||||||
|
<td>Count</td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach($depot_items as $item): ?>
|
||||||
|
<tr>
|
||||||
|
<td><img src="<?php echo "http://".$server."/".$item['itemtype'].".".$imageType; ?>" alt="Item Image"></td>
|
||||||
|
<td><a href="/market.php?compare=<?php echo $item['itemtype']; ?>" target="_BLANK"><?php echo (isset($items[$item['itemtype']])) ? $items[$item['itemtype']] : $item['itemtype']; ?></a></td>
|
||||||
|
<td><?php echo $item['count']; ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
<?php endif;
|
||||||
|
} else {
|
||||||
|
$action = 'list';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are adding a character to the list
|
||||||
|
// silently continues to list
|
||||||
|
if ($action === 'add') {
|
||||||
|
$pid = (isset($_POST['pid']) && (int)$_POST['pid'] > 0) ? (int)$_POST['pid'] : false;
|
||||||
|
$cost = (isset($_POST['cost']) && (int)$_POST['cost'] > 0) ? (int)$_POST['cost'] : false;
|
||||||
|
$deposit = (int)$cost * ($auction['deposit'] / 100);
|
||||||
|
$password = SHA1($_POST['password']);
|
||||||
|
|
||||||
|
// Verify values
|
||||||
|
$status = false;
|
||||||
|
$account = false;
|
||||||
|
if ($pid > 0 && $cost >= $auction['lowestPrice']) {
|
||||||
|
$account = mysql_select_single("
|
||||||
|
SELECT `a`.`id`, `a`.`password`, `za`.`points`
|
||||||
|
FROM `accounts` a
|
||||||
|
INNER JOIN `znote_accounts` za
|
||||||
|
ON `a`.`id` = `za`.`account_id`
|
||||||
|
WHERE `a`.`id`= {$this_account_id}
|
||||||
|
AND `a`.`password`='{$password}'
|
||||||
|
AND `za`.`points` >= {$deposit}
|
||||||
|
LIMIT 1
|
||||||
|
;");
|
||||||
|
if (isset($account['password']) && $account['password'] === $password) {
|
||||||
|
// Check if player exist, is offline and not already in auction
|
||||||
|
// And is not a tutor or a GM+.
|
||||||
|
$player = mysql_select_single("
|
||||||
|
SELECT `p`.`id`, `p`.`name`,
|
||||||
|
CASE
|
||||||
|
WHEN `po`.`player_id` IS NULL
|
||||||
|
THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END AS `online`,
|
||||||
|
CASE
|
||||||
|
WHEN `za`.`player_id` IS NULL
|
||||||
|
THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END AS `alreadyInAuction`
|
||||||
|
FROM `players` p
|
||||||
|
LEFT JOIN `players_online` po
|
||||||
|
ON `p`.`id` = `po`.`player_id`
|
||||||
|
LEFT JOIN `znote_auction_player` za
|
||||||
|
ON `p`.`id` = `za`.`player_id`
|
||||||
|
AND `p`.`account_id` = `za`.`original_account_id`
|
||||||
|
AND `za`.`claimed` = 0
|
||||||
|
WHERE `p`.`id` = {$pid}
|
||||||
|
AND `p`.`account_id` = {$this_account_id}
|
||||||
|
AND `p`.`group_id` = 1
|
||||||
|
LIMIT 1
|
||||||
|
;");
|
||||||
|
if (isset($player['online']) && $player['online'] == 0) {
|
||||||
|
if (isset($player['alreadyInAuction']) && $player['alreadyInAuction'] == 0) {
|
||||||
|
$status = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($status) {
|
||||||
|
$time_begin = time();
|
||||||
|
$time_end = $time_begin + ($auction['biddingDuration']);
|
||||||
|
// Insert row to znote_auction_player
|
||||||
|
mysql_insert("
|
||||||
|
INSERT INTO `znote_auction_player` (
|
||||||
|
`player_id`,
|
||||||
|
`original_account_id`,
|
||||||
|
`bidder_account_id`,
|
||||||
|
`time_begin`,
|
||||||
|
`time_end`,
|
||||||
|
`price`,
|
||||||
|
`bid`,
|
||||||
|
`deposit`,
|
||||||
|
`sold`,
|
||||||
|
`claimed`
|
||||||
|
) VALUES (
|
||||||
|
{$pid},
|
||||||
|
{$this_account_id},
|
||||||
|
0,
|
||||||
|
{$time_begin},
|
||||||
|
{$time_end},
|
||||||
|
{$cost},
|
||||||
|
0,
|
||||||
|
{$deposit},
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
");
|
||||||
|
// Move player to storage account
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `players`
|
||||||
|
SET `account_id` = {$auction['storage_account_id']}
|
||||||
|
WHERE `id` = {$pid}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// Hide character from public character list (in pidprofile.php)
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_players`
|
||||||
|
SET `hide_char` = 1
|
||||||
|
WHERE `player_id` = {$pid}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// Remove deposit from account
|
||||||
|
$afterDeposit = $account['points'] - $deposit;
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_accounts`
|
||||||
|
SET `points` = {$afterDeposit}
|
||||||
|
WHERE `account_id` = {$account['id']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
}
|
||||||
|
$action = 'list';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are refunding a player back to its original owner
|
||||||
|
// silently continues to list
|
||||||
|
if ($action === 'refund') {
|
||||||
|
$zaid = (isset($_POST['zaid']) && (int)$_POST['zaid'] > 0) ? (int)$_POST['zaid'] : false;
|
||||||
|
//data_dump($_POST, false, "POST");
|
||||||
|
if ($zaid !== false) {
|
||||||
|
$time = time();
|
||||||
|
// If original account is the one trying to get it back,
|
||||||
|
// and bidding period is over,
|
||||||
|
// and its not labelled as sold
|
||||||
|
// and nobody has bid on it
|
||||||
|
$character = mysql_select_single("
|
||||||
|
SELECT `player_id`
|
||||||
|
FROM `znote_auction_player`
|
||||||
|
WHERE `id`= {$zaid}
|
||||||
|
AND `original_account_id` = {$this_account_id}
|
||||||
|
AND `time_end` <= {$time}
|
||||||
|
AND `bidder_account_id` = 0
|
||||||
|
AND `bid` = 0
|
||||||
|
AND `sold` = 0
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
//data_dump($character, false, "Character");
|
||||||
|
if ($character !== false) {
|
||||||
|
// Move character to buyer account and give it a new name
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `players`
|
||||||
|
SET `account_id` = {$this_account_id}
|
||||||
|
WHERE `id` = {$character['player_id']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// Set label to sold
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_auction_player`
|
||||||
|
SET `sold` = 1
|
||||||
|
WHERE `id`= {$zaid}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// Show character in public character list (in characterprofile.php)
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_players`
|
||||||
|
SET `hide_char` = 0
|
||||||
|
WHERE `player_id` = {$character['player_id']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$action = 'list';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are claiming a character
|
||||||
|
// If validation fails then explain why, but then head over to list regardless of status
|
||||||
|
if ($action === 'claim') {
|
||||||
|
$zaid = (isset($_POST['zaid']) && (int)$_POST['zaid'] > 0) ? (int)$_POST['zaid'] : false;
|
||||||
|
$name = (isset($_POST['name']) && !empty($_POST['name'])) ? getValue($_POST['name']) : false;
|
||||||
|
$errors = array();
|
||||||
|
//data_dump($_POST, $name, "Post data:");
|
||||||
|
if ($zaid === false) {
|
||||||
|
$errors[] = 'We are unable to find this auction order.';
|
||||||
|
}
|
||||||
|
if ((int)$auction['storage_account_id'] === $this_account_id) {
|
||||||
|
$errors[] = 'Silly you! You cannot claim characters with the storage account configured in <br>$config[\'shop_auction\'][\'storage_account_id\']<br>because you already have those characters in your account! :P';
|
||||||
|
if ($is_admin) {
|
||||||
|
$errors[] = "ADMIN: The storage account in config.php should not be the same as the admin account.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($name === false) {
|
||||||
|
$errors[] = 'Please give the character a name.';
|
||||||
|
} else {
|
||||||
|
// begin name validation
|
||||||
|
$name = validate_name($name);
|
||||||
|
if (user_character_exist($name) !== false) {
|
||||||
|
$errors[] = 'Sorry, that character name already exist.';
|
||||||
|
}
|
||||||
|
if (!preg_match("/^[a-zA-Z_ ]+$/", $name)) {
|
||||||
|
$errors[] = 'Your name may only contain a-z, A-Z and spaces.';
|
||||||
|
}
|
||||||
|
if (strlen($name) < $config['minL'] || strlen($name) > $config['maxL']) {
|
||||||
|
$errors[] = 'Your character name must be between ' . $config['minL'] . ' - ' . $config['maxL'] . ' characters long.';
|
||||||
|
}
|
||||||
|
// name restriction
|
||||||
|
$resname = explode(" ", $name);
|
||||||
|
foreach($resname as $res) {
|
||||||
|
if(in_array(strtolower($res), $config['invalidNameTags'])) {
|
||||||
|
$errors[] = 'Your username contains a restricted word.';
|
||||||
|
}
|
||||||
|
else if(strlen($res) == 1) {
|
||||||
|
$errors[] = 'Too short words in your name.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$name = format_character_name($name);
|
||||||
|
// end name validation
|
||||||
|
if (empty($errors)) {
|
||||||
|
// Make sure you have access to claim this zaid character.
|
||||||
|
// And that you havent already claimed it.
|
||||||
|
// And that the character isn't online...
|
||||||
|
$character = mysql_select_single("
|
||||||
|
SELECT
|
||||||
|
`za`.`id` AS `zaid`,
|
||||||
|
`za`.`player_id`,
|
||||||
|
`p`.`account_id`
|
||||||
|
FROM `znote_auction_player` za
|
||||||
|
INNER JOIN `players` p
|
||||||
|
ON `za`.`player_id` = `p`.`id`
|
||||||
|
LEFT JOIN `players_online` po
|
||||||
|
ON `p`.`id` = `po`.`player_id`
|
||||||
|
WHERE `za`.`id` = {$zaid}
|
||||||
|
AND `za`.`sold` = 1
|
||||||
|
AND `p`.`account_id` != {$this_account_id}
|
||||||
|
AND `za`.`bidder_account_id` = {$this_account_id}
|
||||||
|
AND `po`.`player_id` IS NULL
|
||||||
|
");
|
||||||
|
//data_dump($character, false, "Character");
|
||||||
|
if ($character !== false) {
|
||||||
|
// Set character to claimed
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_auction_player`
|
||||||
|
SET `claimed`='1'
|
||||||
|
WHERE `id` = {$character['zaid']}
|
||||||
|
");
|
||||||
|
// Move character to buyer account and give it a new name
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `players`
|
||||||
|
SET `name` = '{$name}',
|
||||||
|
`account_id` = {$this_account_id}
|
||||||
|
WHERE `id` = {$character['player_id']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// Show character in public character list (in characterprofile.php)
|
||||||
|
mysql_update("
|
||||||
|
UPDATE `znote_players`
|
||||||
|
SET `hide_char` = 0
|
||||||
|
WHERE `player_id` = {$character['player_id']}
|
||||||
|
LIMIT 1;
|
||||||
|
");
|
||||||
|
// Remove character from other players VIP lists
|
||||||
|
mysql_delete("
|
||||||
|
DELETE FROM `account_viplist`
|
||||||
|
WHERE `player_id` = {$character['player_id']}
|
||||||
|
");
|
||||||
|
// Remove the character deathlist
|
||||||
|
mysql_delete("
|
||||||
|
DELETE FROM `player_deaths`
|
||||||
|
WHERE `player_id` = {$character['player_id']}
|
||||||
|
");
|
||||||
|
} else {
|
||||||
|
$errors[] = "You either don't have access to claim this character, or you have already claimed it, or this character isn't sold yet, or we were unable to find this auction order.";
|
||||||
|
if ($is_admin) {
|
||||||
|
$errors[] = "ADMIN: ... Or character is online.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($errors)) {
|
||||||
|
//data_dump($errors, false, "Errors:");
|
||||||
|
?>
|
||||||
|
<table class="auction_error">
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>#</td>
|
||||||
|
<td>Issues occured while claiming your name</td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach($errors as $i => $error): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $i+1; ?></td>
|
||||||
|
<td><?php echo $error; ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
$action = 'list';
|
||||||
|
}
|
||||||
|
|
||||||
|
// List characters currently in the auction
|
||||||
|
if ($action === 'list') {
|
||||||
|
// If this account have successfully bought or won an auction
|
||||||
|
// Intercept the list action and let the user do claim actions
|
||||||
|
$pending = mysql_select_multi("
|
||||||
|
SELECT
|
||||||
|
`za`.`id` AS `zaid`,
|
||||||
|
CASE WHEN `za`.`price` > `za`.`bid`
|
||||||
|
THEN `za`.`price`
|
||||||
|
ELSE `za`.`bid`
|
||||||
|
END AS `price`,
|
||||||
|
`za`.`time_begin`,
|
||||||
|
`za`.`time_end`,
|
||||||
|
`p`.`vocation`,
|
||||||
|
`p`.`level`,
|
||||||
|
`p`.`lookbody` AS `body`,
|
||||||
|
`p`.`lookfeet` AS `feet`,
|
||||||
|
`p`.`lookhead` AS `head`,
|
||||||
|
`p`.`looklegs` AS `legs`,
|
||||||
|
`p`.`looktype` AS `type`,
|
||||||
|
`p`.`lookaddons` AS `addons`
|
||||||
|
FROM `znote_auction_player` za
|
||||||
|
INNER JOIN `players` p
|
||||||
|
ON `za`.`player_id` = `p`.`id`
|
||||||
|
WHERE `p`.`account_id` = {$auction['storage_account_id']}
|
||||||
|
AND `za`.`claimed` = 0
|
||||||
|
AND `za`.`sold` = 1
|
||||||
|
AND `za`.`bidder_account_id` = {$this_account_id}
|
||||||
|
ORDER BY `p`.`level` desc
|
||||||
|
");
|
||||||
|
//data_dump($pending, false, "Pending characters:");
|
||||||
|
if ($pending !== false) {
|
||||||
|
?>
|
||||||
|
<h2>Congratulations!</h2>
|
||||||
|
<p>You have <?php echo (COUNT($pending) > 1) ? 'characters' : 'a character'; ?> ready to claim!</p>
|
||||||
|
<?php foreach($pending as $character): ?>
|
||||||
|
<table class="auction_char">
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>Level</td>
|
||||||
|
<td>Vocation</td>
|
||||||
|
<td>Details</td>
|
||||||
|
<td>Price</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $character['level']; ?></td>
|
||||||
|
<td><?php echo vocation_id_to_name($character['vocation']); ?></td>
|
||||||
|
<td><a href="/auctionChar.php?action=view&zaid=<?php echo $character['zaid']; ?>">VIEW</a></td>
|
||||||
|
<td><?php echo $character['price']; ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<?php if ($loadOutfits): ?>
|
||||||
|
<td class="outfitColumn">
|
||||||
|
<img src="<?php echo $config['show_outfits']['imageServer']; ?>?id=<?php echo $character['type']; ?>&addons=<?php echo $character['addons']; ?>&head=<?php echo $character['head']; ?>&body=<?php echo $character['body']; ?>&legs=<?php echo $character['legs']; ?>&feet=<?php echo $character['feet']; ?>" alt="img">
|
||||||
|
</td>
|
||||||
|
<?php endif; ?>
|
||||||
|
<td colspan="3">
|
||||||
|
<p>Hello master, what should my new name be?</p>
|
||||||
|
<form action="/auctionChar.php" method="POST">
|
||||||
|
<input type="hidden" name="action" value="claim">
|
||||||
|
<input type="hidden" name="zaid" value="<?php echo $character['zaid']; ?>">
|
||||||
|
<input type="text" name="name">
|
||||||
|
<input type="submit" value="Claim character">
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<h2>Ongoing auctions:</h2>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the list
|
||||||
|
$characters = mysql_select_multi("
|
||||||
|
SELECT
|
||||||
|
`za`.`id` AS `zaid`,
|
||||||
|
CASE WHEN `za`.`price` > `za`.`bid`
|
||||||
|
THEN `za`.`price`
|
||||||
|
ELSE `za`.`bid`+{$step}
|
||||||
|
END AS `price`,
|
||||||
|
`za`.`time_begin`,
|
||||||
|
`za`.`time_end`,
|
||||||
|
`p`.`vocation`,
|
||||||
|
`p`.`level`,
|
||||||
|
`p`.`lookbody` AS `body`,
|
||||||
|
`p`.`lookfeet` AS `feet`,
|
||||||
|
`p`.`lookhead` AS `head`,
|
||||||
|
`p`.`looklegs` AS `legs`,
|
||||||
|
`p`.`looktype` AS `type`,
|
||||||
|
`p`.`lookaddons` AS `addons`
|
||||||
|
FROM `znote_auction_player` za
|
||||||
|
INNER JOIN `players` p
|
||||||
|
ON `za`.`player_id` = `p`.`id`
|
||||||
|
WHERE `p`.`account_id` = {$auction['storage_account_id']}
|
||||||
|
AND `za`.`sold` = 0
|
||||||
|
ORDER BY `p`.`level` desc;
|
||||||
|
");
|
||||||
|
//data_dump($characters, false, "List characters");
|
||||||
|
if ($is_admin) {
|
||||||
|
?>
|
||||||
|
<p>Admin: <a href="/admin_auction.php">Character auction history</a></p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if (is_array($characters) && !empty($characters)):
|
||||||
|
?>
|
||||||
|
<table class="auction_char">
|
||||||
|
<tr class="yellow">
|
||||||
|
<td>Level</td>
|
||||||
|
<td>Vocation</td>
|
||||||
|
<?php if ($loadOutfits): ?>
|
||||||
|
<td>Image</td>
|
||||||
|
<?php endif; ?>
|
||||||
|
<td>Details</td>
|
||||||
|
<td>Price</td>
|
||||||
|
<td>Added</td>
|
||||||
|
<td>Type</td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach($characters as $character): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $character['level']; ?></td>
|
||||||
|
<td><?php echo vocation_id_to_name($character['vocation']); ?></td>
|
||||||
|
<?php if ($loadOutfits): ?>
|
||||||
|
<td class="outfitColumn">
|
||||||
|
<img src="<?php echo $config['show_outfits']['imageServer']; ?>?id=<?php echo $character['type']; ?>&addons=<?php echo $character['addons']; ?>&head=<?php echo $character['head']; ?>&body=<?php echo $character['body']; ?>&legs=<?php echo $character['legs']; ?>&feet=<?php echo $character['feet']; ?>" alt="img">
|
||||||
|
</td>
|
||||||
|
<?php endif; ?>
|
||||||
|
<td><a href="/auctionChar.php?action=view&zaid=<?php echo $character['zaid']; ?>">VIEW</a></td>
|
||||||
|
<td><?php echo $character['price']; ?></td>
|
||||||
|
<td><?php
|
||||||
|
$ended = (time() > $character['time_end']) ? true : false;
|
||||||
|
echo getClock($character['time_begin'], true);
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<td><?php echo ($ended) ? 'Instant' : 'Bidding<br>('.toDuration(($character['time_end'] - time())).')'; ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
<?php
|
||||||
|
endif;
|
||||||
|
?>
|
||||||
|
<p><a href="/auctionChar.php?action=create">Add a character to the auction</a>.</p>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
} elseif ($action === 'create') { // Add player to auction view
|
||||||
|
$minToCreate = (int)ceil(($auction['lowestPrice'] / 100) * $auction['deposit']);
|
||||||
|
$own_characters = mysql_select_multi("
|
||||||
|
SELECT
|
||||||
|
`p`.`id`,
|
||||||
|
`p`.`name`,
|
||||||
|
`p`.`level`,
|
||||||
|
`p`.`vocation`,
|
||||||
|
`a`.`points`
|
||||||
|
FROM `players` p
|
||||||
|
INNER JOIN `znote_accounts` a
|
||||||
|
ON `p`.`account_id` = `a`.`account_id`
|
||||||
|
LEFT JOIN `znote_auction_player` za
|
||||||
|
ON `p`.`id` = `za`.`player_id`
|
||||||
|
AND `p`.`account_id` = `za`.`original_account_id`
|
||||||
|
AND `za`.`claimed` = 0
|
||||||
|
LEFT JOIN `players_online` po
|
||||||
|
ON `p`.`id` = `po`.`player_id`
|
||||||
|
WHERE `p`.`account_id`={$this_account_id}
|
||||||
|
AND `za`.`player_id` IS NULL
|
||||||
|
AND `po`.`player_id` IS NULL
|
||||||
|
AND `p`.`level` >= {$auction['lowestLevel']}
|
||||||
|
AND `a`.`points` >= $minToCreate
|
||||||
|
;");
|
||||||
|
//data_dump($own_characters, false, "own_chars");
|
||||||
|
|
||||||
|
if (is_array($own_characters) && !empty($own_characters)) {
|
||||||
|
$max = ($own_characters[0]['points'] / $auction['deposit']) * 100;
|
||||||
|
?>
|
||||||
|
<p><a href="/auctionChar.php?action=list">Go back to list.</a></p>
|
||||||
|
<form action="/auctionChar.php" method="POST">
|
||||||
|
<input type="hidden" name="action" value="add">
|
||||||
|
<p>Character: (Must be offline)</p>
|
||||||
|
<select name="pid">
|
||||||
|
<?php if(is_array($own_characters) && !empty($own_characters))
|
||||||
|
foreach($own_characters as $char): ?>
|
||||||
|
<option value="<?php echo $char['id']; ?>">
|
||||||
|
<?php echo "Level: ", $char['level'], " ", vocation_id_to_name($char['vocation']), ": ", $char['name']; ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
<p><strong>Shop points:</strong>
|
||||||
|
<br>Your current points: <?php echo $own_characters[0]['points']; ?>
|
||||||
|
<br>Minimum: <?php echo $auction['lowestPrice']; ?>
|
||||||
|
<br>deposit: <?php echo $auction['deposit']; ?>%
|
||||||
|
<br>Your maximum: <?php echo $max; ?>
|
||||||
|
</p>
|
||||||
|
<p><strong>Deposit information:</strong>
|
||||||
|
<br>To ensure you as the seller is a legitimate account, and to encourage fair prices you have to temporarily invest <?php echo $auction['deposit']; ?>% of the selling price as a deposit.
|
||||||
|
</p>
|
||||||
|
<p>Once the auction has completed, the deposit fee will be refunded back to your account.</p>
|
||||||
|
<p>If you wish to reclaim your character, you can do it after the bidding period if nobody has placed an offer on it. But if you do this you will not get the deposit back. It is therefore advisable that you create a good and appealing offer to our community.</p>
|
||||||
|
<p>Sell price:</p>
|
||||||
|
<input type="number" name="cost" min="<?php echo $auction['lowestPrice']; ?>" max="<?php echo $max; ?>" step="5" placeholder="<?php echo $auction['lowestPrice']; ?> - <?php echo $max; ?>">
|
||||||
|
<br>
|
||||||
|
<p>Verify with your password:</p>
|
||||||
|
<input type="password" name="password">
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Sell character">
|
||||||
|
</form>
|
||||||
|
<?php
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<p><a href="/auctionChar.php?action=list">Go back to list.</a></p>
|
||||||
|
<p>Your account does not follow the required rules to sell characters.
|
||||||
|
<br>1. Minimum level: <?php echo $auction['lowestLevel']; ?>
|
||||||
|
<br>2. Minimum already earned shop points: <?php echo $minToCreate; ?>
|
||||||
|
<br>3. Eligible characters must be offline.
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
} else echo "<p>Character shop auctioning system is disabled.</p>";
|
} else echo "<p>Character shop auctioning system is disabled.</p>";
|
||||||
|
include 'layout/overall/footer.php'; ?>
|
||||||
include 'layout/overall/footer.php'; ?>
|
|
||||||
|
|
21
config.php
21
config.php
@ -926,15 +926,24 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
/// Let players sell characters.
|
/// Let players sell, buy and bid on characters.
|
||||||
|
/// Creates a deeper shop economy, encourages players to spend more money in shop for points.
|
||||||
|
/// Pay to win/progress mechanic, but also lets people who can barely afford points to gain it
|
||||||
|
/// by leveling characters to sell. It can also discourages illegal/risky third-party account
|
||||||
|
/// services. Since players can buy officially & support the server, dodgy competitors have to sell for cheaper.
|
||||||
|
/// Without admin interference this is organic to each individual community economy inflation.
|
||||||
/////////
|
/////////
|
||||||
$config['shop_auction'] = array(
|
$config['shop_auction'] = array(
|
||||||
'characterAuction' => false, // Enable/disable this system
|
'characterAuction' => false, // Enable/disable this system
|
||||||
'requiredLevel' => 50, // Minimum level of sold character
|
// Account ID of the account that stores players in the auction.
|
||||||
'leastValue' => 10, // Lowest donation points a char can be sold for.
|
// Make sure storage account has a very secure password!
|
||||||
'leastTime' => 24, // In hours. False to disable.
|
'storage_account_id' => 5, // Separate secure account ID, not your GM.
|
||||||
// leastTime = Lowest duration of time an auctioned player has to be
|
'step' => 5, // Minimum amount someone can raise a bid by
|
||||||
// sellable before auctioneer can claim character back.
|
'step_duration' => 1 * 60 * 60, // When bidding over someone else, extend bid period by 1 hour.
|
||||||
|
'lowestLevel' => 20, // Minimum level of sold character
|
||||||
|
'lowestPrice' => 10, // Lowest donation points a char can be sold for.
|
||||||
|
'biddingDuration' => 1 * 24 * 60 * 60, // = 1 day, 0 to disable bidding
|
||||||
|
'deposit' => 10 // Seller has to add 10=10% deposit to auction which he gets back later.
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -250,6 +250,21 @@ CREATE TABLE IF NOT EXISTS `znote_global_storage` (
|
|||||||
UNIQUE (`key`)
|
UNIQUE (`key`)
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `znote_auction_player` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`player_id` int(11) NOT NULL,
|
||||||
|
`original_account_id` int(11) NOT NULL,
|
||||||
|
`bidder_account_id` int(11) NOT NULL,
|
||||||
|
`time_begin` int(11) NOT NULL,
|
||||||
|
`time_end` int(11) NOT NULL,
|
||||||
|
`price` int(11) NOT NULL,
|
||||||
|
`bid` int(11) NOT NULL,
|
||||||
|
`deposit` int(11) NOT NULL,
|
||||||
|
`sold` tinyint(1) NOT NULL,
|
||||||
|
`claimed` tinyint(1) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
INSERT INTO `znote` (`version`, `installed`) VALUES
|
INSERT INTO `znote` (`version`, `installed`) VALUES
|
||||||
('$version', '$time');
|
('$version', '$time');
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
<ul> <!-- (sub)dropdown SHOP -->
|
<ul> <!-- (sub)dropdown SHOP -->
|
||||||
<li><a href="buypoints.php">Buy Points</a></li>
|
<li><a href="buypoints.php">Buy Points</a></li>
|
||||||
<li><a href="shop.php">Shop Offers</a></li>
|
<li><a href="shop.php">Shop Offers</a></li>
|
||||||
|
<?php if ($config['shop_auction']['characterAuction']): ?>
|
||||||
|
<li><a href="auctionChar.php">Character Auction</a></li>
|
||||||
|
<?php endif; ?>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="guilds.php">Guilds</a>
|
<li><a href="guilds.php">Guilds</a>
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<a href='admin_shop.php'>Admin Shop</a>
|
<a href='admin_shop.php'>Admin Shop</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href='admin_auction.php'>Admin Auction</a>
|
||||||
|
</li>
|
||||||
<?php
|
<?php
|
||||||
$new = 0;
|
$new = 0;
|
||||||
$cat = 4; //Category ID for feedback section
|
$cat = 4; //Category ID for feedback section
|
||||||
|
Loading…
x
Reference in New Issue
Block a user