| @@ -0,0 +1,59 @@ | |||
| 1 | + | -- recursive dump function | |
| 2 | + | function dumpLevel(input, level) | |
| 3 | + | local indent = '' | |
| 4 | + | ||
| 5 | + | for i = 1, level do | |
| 6 | + | indent = indent .. ' ' | |
| 7 | + | end | |
| 8 | + | ||
| 9 | + | if type(input) == 'table' then | |
| 10 | + | local str = '{ \n' | |
| 11 | + | local lines = {} | |
| 12 | + | ||
| 13 | + | for k, v in pairs(input) do | |
| 14 | + | if type(k) ~= 'number' then | |
| 15 | + | k = '"' .. k .. '"' | |
| 16 | + | end | |
| 17 | + | ||
| 18 | + | if type(v) == 'string' then | |
| 19 | + | v = '"' .. v .. '"' | |
| 20 | + | end | |
| 21 | + | ||
| 22 | + | table.insert(lines, indent .. ' [' .. k .. '] = ' .. dumpLevel(v, level + 1)) | |
| 23 | + | end | |
| 24 | + | return str .. table.concat(lines, ',\n') .. '\n' .. indent .. '}' | |
| 25 | + | end | |
| 26 | + | ||
| 27 | + | return tostring(input) | |
| 28 | + | end | |
| 29 | + | ||
| 30 | + | -- Return a string representation of input for debugging purposes | |
| 31 | + | function dump(input) | |
| 32 | + | return dumpLevel(input, 0) | |
| 33 | + | end | |
| 34 | + | ||
| 35 | + | -- Call the dump function and print it to console | |
| 36 | + | function pdump(input) | |
| 37 | + | local dump_str = dump(input) | |
| 38 | + | print(dump_str) | |
| 39 | + | return dump_str | |
| 40 | + | end | |
| 41 | + | ||
| 42 | + | -- Call the dump function with a title and print it beautifully to the console | |
| 43 | + | function tdump(title, input) | |
| 44 | + | local title_fill = '' | |
| 45 | + | for i = 1, title:len() do | |
| 46 | + | title_fill = title_fill .. '=' | |
| 47 | + | end | |
| 48 | + | ||
| 49 | + | local header_str = '\n====' .. title_fill .. '====\n' | |
| 50 | + | header_str = header_str .. '=== ' .. title .. ' ===\n' | |
| 51 | + | header_str = header_str .. '====' .. title_fill .. '====\n' | |
| 52 | + | ||
| 53 | + | local dump_str = dump(input) | |
| 54 | + | local footer_str = '\n====' .. title_fill .. '====\n' | |
| 55 | + | ||
| 56 | + | print(header_str .. dump_str .. footer_str) | |
| 57 | + | ||
| 58 | + | return dump_str | |
| 59 | + | end |
| @@ -0,0 +1,5 @@ | |||
| 1 | + | if type(jit) == 'table' then | |
| 2 | + | print('>> Using ' .. jit.version) --LuaJIT 2.0.2 | |
| 3 | + | else | |
| 4 | + | print('>> Using ' .. _VERSION) | |
| 5 | + | end |
| @@ -0,0 +1,18 @@ | |||
| 1 | + | -- Core API functions implemented in Lua | |
| 2 | + | dofile('data/lib/core/core.lua') | |
| 3 | + | ||
| 4 | + | -- Compatibility library for our old Lua API | |
| 5 | + | dofile('data/lib/compat/compat.lua') | |
| 6 | + | ||
| 7 | + | -- Custom systems (ex Tibiagun) | |
| 8 | + | dofile('data/lib/custom/SYSTEM.lua') | |
| 9 | + | dofile('data/lib/custom/ITEMS.lua') | |
| 10 | + | ||
| 11 | + | -- Debugging helper function for Lua developers | |
| 12 | + | dofile('data/lib/debugging/dump.lua') | |
| 13 | + | dofile('data/lib/debugging/lua_version.lua') | |
| 14 | + | ||
| 15 | + | dofile('data/lib/core/json.lua') | |
| 16 | + | ||
| 17 | + | -- Systems | |
| 18 | + | --dofile('data/lib/systems/systems.lua') |
| @@ -0,0 +1,7 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 1 (account names)") | |
| 3 | + | db.query("ALTER TABLE `accounts` ADD `name` VARCHAR(32) NOT NULL AFTER `id`") | |
| 4 | + | db.query("UPDATE `accounts` SET `name` = `id`") | |
| 5 | + | db.query("ALTER TABLE `accounts` ADD UNIQUE (`name`)") | |
| 6 | + | return true | |
| 7 | + | end |
| @@ -0,0 +1,5 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 2 (market offers)") | |
| 3 | + | db.query("CREATE TABLE `market_offers` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `player_id` INT NOT NULL, `sale` TINYINT(1) NOT NULL DEFAULT 0, `itemtype` INT UNSIGNED NOT NULL, `amount` SMALLINT UNSIGNED NOT NULL, `created` BIGINT UNSIGNED NOT NULL, `anonymous` TINYINT(1) NOT NULL DEFAULT 0, `price` INT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY(`sale`, `itemtype`), KEY(`created`), FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE) ENGINE = InnoDB") | |
| 4 | + | return true | |
| 5 | + | end |
| @@ -0,0 +1,5 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 3 (bank balance)") | |
| 3 | + | db.query("ALTER TABLE `players` ADD `balance` BIGINT UNSIGNED NOT NULL DEFAULT 0") | |
| 4 | + | return true | |
| 5 | + | end |
| @@ -0,0 +1,5 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 4 (market history)") | |
| 3 | + | db.query("CREATE TABLE `market_history` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `player_id` INT NOT NULL, `sale` TINYINT(1) NOT NULL DEFAULT 0, `itemtype` INT UNSIGNED NOT NULL, `amount` SMALLINT UNSIGNED NOT NULL, `price` INT UNSIGNED NOT NULL DEFAULT 0, `expires_at` BIGINT UNSIGNED NOT NULL, `inserted` BIGINT UNSIGNED NOT NULL, `state` TINYINT(1) UNSIGNED NOT NULL, PRIMARY KEY(`id`), KEY(`player_id`, `sale`), FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE) ENGINE = InnoDB") | |
| 4 | + | return true | |
| 5 | + | end |
| @@ -0,0 +1,7 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 5 (black skull & guild wars)") | |
| 3 | + | db.query("ALTER TABLE `players` CHANGE `redskull` `skull` TINYINT(1) NOT NULL DEFAULT '0', CHANGE `redskulltime` `skulltime` INT(11) NOT NULL DEFAULT '0'") | |
| 4 | + | db.query("CREATE TABLE IF NOT EXISTS `guild_wars` ( `id` int(11) NOT NULL AUTO_INCREMENT, `guild1` int(11) NOT NULL DEFAULT '0', `guild2` int(11) NOT NULL DEFAULT '0', `name1` varchar(255) NOT NULL, `name2` varchar(255) NOT NULL, `status` tinyint(2) NOT NULL DEFAULT '0', `started` bigint(15) NOT NULL DEFAULT '0', `ended` bigint(15) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `guild1` (`guild1`), KEY `guild2` (`guild2`)) ENGINE=InnoDB") | |
| 5 | + | db.query("CREATE TABLE IF NOT EXISTS `guildwar_kills` (`id` int(11) NOT NULL AUTO_INCREMENT, `killer` varchar(50) NOT NULL, `target` varchar(50) NOT NULL, `killerguild` int(11) NOT NULL DEFAULT '0', `targetguild` int(11) NOT NULL DEFAULT '0', `warid` int(11) NOT NULL DEFAULT '0', `time` bigint(15) NOT NULL, PRIMARY KEY (`id`), KEY `warid` (`warid`), FOREIGN KEY (`warid`) REFERENCES `guild_wars`(`id`) ON DELETE CASCADE) ENGINE=InnoDB") | |
| 6 | + | return true | |
| 7 | + | end |
| @@ -0,0 +1,5 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 6 (market bug fix)") | |
| 3 | + | db.query("DELETE FROM `market_offers` WHERE `amount` = 0") | |
| 4 | + | return true | |
| 5 | + | end |
| @@ -0,0 +1,6 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 7 (offline training)") | |
| 3 | + | db.query("ALTER TABLE `players` ADD `offlinetraining_time` SMALLINT UNSIGNED NOT NULL DEFAULT 43200") | |
| 4 | + | db.query("ALTER TABLE `players` ADD `offlinetraining_skill` INT NOT NULL DEFAULT -1") | |
| 5 | + | return true | |
| 6 | + | end |
| @@ -0,0 +1,35 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 8 (account viplist with description, icon and notify server side)") | |
| 3 | + | db.query("RENAME TABLE `player_viplist` TO `account_viplist`") | |
| 4 | + | db.query("ALTER TABLE `account_viplist` DROP FOREIGN KEY `account_viplist_ibfk_1`") | |
| 5 | + | db.query("UPDATE `account_viplist` SET `player_id` = (SELECT `account_id` FROM `players` WHERE `id` = `player_id`)") | |
| 6 | + | db.query("ALTER TABLE `account_viplist` CHANGE `player_id` `account_id` INT( 11 ) NOT NULL COMMENT 'id of account whose viplist entry it is'") | |
| 7 | + | db.query("ALTER TABLE `account_viplist` DROP FOREIGN KEY `account_viplist_ibfk_2`") | |
| 8 | + | db.query("ALTER TABLE `account_viplist` CHANGE `vip_id` `player_id` INT( 11 ) NOT NULL COMMENT 'id of target player of viplist entry'") | |
| 9 | + | db.query("ALTER TABLE `account_viplist` DROP INDEX `player_id`, ADD INDEX `account_id` (`account_id`)") | |
| 10 | + | db.query("ALTER TABLE `account_viplist` DROP INDEX `vip_id`, ADD INDEX `player_id` (`player_id`)") | |
| 11 | + | db.query("ALTER TABLE `account_viplist` ADD FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE") | |
| 12 | + | db.query("ALTER TABLE `account_viplist` ADD FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE") | |
| 13 | + | db.query("ALTER TABLE `account_viplist` ADD `description` VARCHAR(128) NOT NULL DEFAULT '', ADD `icon` TINYINT( 2 ) UNSIGNED NOT NULL DEFAULT '0', ADD `notify` TINYINT( 1 ) NOT NULL DEFAULT '0'") | |
| 14 | + | ||
| 15 | + | -- Remove duplicates | |
| 16 | + | local resultId = db.storeQuery("SELECT `account_id`, `player_id`, COUNT(*) AS `count` FROM `account_viplist` GROUP BY `account_id`, `player_id` HAVING COUNT(*) > 1") | |
| 17 | + | if resultId ~= false then | |
| 18 | + | repeat | |
| 19 | + | db.query("DELETE FROM `account_viplist` WHERE `account_id` = " .. result.getNumber(resultId, "account_id") .. " AND `player_id` = " .. result.getNumber(resultId, "player_id") .. " LIMIT " .. (result.getNumber(resultId, "count") - 1)) | |
| 20 | + | until not result.next(resultId) | |
| 21 | + | result.free(resultId) | |
| 22 | + | end | |
| 23 | + | ||
| 24 | + | -- Remove if an account has over 200 entries | |
| 25 | + | resultId = db.storeQuery("SELECT `account_id`, COUNT(*) AS `count` FROM `account_viplist` GROUP BY `account_id` HAVING COUNT(*) > 200") | |
| 26 | + | if resultId ~= false then | |
| 27 | + | repeat | |
| 28 | + | db.query("DELETE FROM `account_viplist` WHERE `account_id` = " .. result.getNumber(resultId, "account_id") .. " LIMIT " .. (result.getNumber(resultId, "count") - 200)) | |
| 29 | + | until not result.next(resultId) | |
| 30 | + | result.free(resultId) | |
| 31 | + | end | |
| 32 | + | ||
| 33 | + | db.query("ALTER TABLE `account_viplist` ADD UNIQUE `account_player_index` (`account_id`, `player_id`)") | |
| 34 | + | return true | |
| 35 | + | end |
| @@ -0,0 +1,70 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 9 (global inbox)") | |
| 3 | + | db.query("CREATE TABLE IF NOT EXISTS `player_inboxitems` (`player_id` int(11) NOT NULL, `sid` int(11) NOT NULL, `pid` int(11) NOT NULL DEFAULT '0', `itemtype` smallint(6) NOT NULL, `count` smallint(5) NOT NULL DEFAULT '0', `attributes` blob NOT NULL, UNIQUE KEY `player_id_2` (`player_id`,`sid`), KEY `player_id` (`player_id`), FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1") | |
| 4 | + | ||
| 5 | + | -- Delete "market" item | |
| 6 | + | db.query("DELETE FROM `player_depotitems` WHERE `itemtype` = 14405") | |
| 7 | + | ||
| 8 | + | -- Move up items in depot chests | |
| 9 | + | local resultId = db.storeQuery("SELECT `player_id`, `pid`, (SELECT `dp2`.`sid` FROM `player_depotitems` AS `dp2` WHERE `dp2`.`player_id` = `dp1`.`player_id` AND `dp2`.`pid` = `dp1`.`sid` AND `itemtype` = 2594) AS `sid` FROM `player_depotitems` AS `dp1` WHERE `itemtype` = 2589") | |
| 10 | + | if resultId ~= false then | |
| 11 | + | repeat | |
| 12 | + | db.query("UPDATE `player_depotitems` SET `pid` = " .. result.getNumber(resultId, "pid") .. " WHERE `player_id` = " .. result.getNumber(resultId, "player_id") .. " AND `pid` = " .. result.getNumber(resultId, "sid")) | |
| 13 | + | until not result.next(resultId) | |
| 14 | + | result.free(resultId) | |
| 15 | + | end | |
| 16 | + | ||
| 17 | + | -- Delete the depot lockers | |
| 18 | + | db.query("DELETE FROM `player_depotitems` WHERE `itemtype` = 2589") | |
| 19 | + | ||
| 20 | + | -- Delete the depot chests | |
| 21 | + | db.query("DELETE FROM `player_depotitems` WHERE `itemtype` = 2594") | |
| 22 | + | ||
| 23 | + | resultId = db.storeQuery("SELECT DISTINCT `player_id` FROM `player_depotitems` WHERE `itemtype` = 14404") | |
| 24 | + | if resultId ~= false then | |
| 25 | + | repeat | |
| 26 | + | local playerId = result.getNumber(resultId, "player_id") | |
| 27 | + | ||
| 28 | + | local runningId = 100 | |
| 29 | + | ||
| 30 | + | local stmt = "INSERT INTO `player_inboxitems` (`player_id`, `sid`, `pid`, `itemtype`, `count`, `attributes`) VALUES " | |
| 31 | + | ||
| 32 | + | local resultId2 = db.storeQuery("SELECT `sid` FROM `player_depotitems` WHERE `player_id` = " .. playerId .. " AND `itemtype` = 14404") | |
| 33 | + | if resultId2 ~= false then | |
| 34 | + | repeat | |
| 35 | + | local sids = {} | |
| 36 | + | sids[#sids + 1] = result.getNumber(resultId2, "sid") | |
| 37 | + | while #sids > 0 do | |
| 38 | + | local sid = sids[#sids] | |
| 39 | + | sids[#sids] = nil | |
| 40 | + | ||
| 41 | + | local resultId3 = db.storeQuery("SELECT * FROM `player_depotitems` WHERE `player_id` = " .. playerId .. " AND `pid` = " .. sid) | |
| 42 | + | if resultId3 ~= false then | |
| 43 | + | repeat | |
| 44 | + | local attr, attrSize = result.getStream(resultId3, "attributes") | |
| 45 | + | runningId = runningId + 1 | |
| 46 | + | stmt = stmt .. "(" .. playerId .. "," .. runningId .. ",0," .. result.getNumber(resultId3, "itemtype") .. "," .. result.getNumber(resultId3, "count") .. "," .. db.escapeBlob(attr, attrSize) .. ")," | |
| 47 | + | sids[#sids + 1] = result.getNumber(resultId3, "sid") | |
| 48 | + | ||
| 49 | + | db.query("DELETE FROM `player_depotitems` WHERE `player_id` = " .. result.getNumber(resultId, "player_id") .. " AND `sid` = " .. result.getNumber(resultId3, "sid")) | |
| 50 | + | until not result.next(resultId3) | |
| 51 | + | result.free(resultId3) | |
| 52 | + | end | |
| 53 | + | end | |
| 54 | + | until not result.next(resultId2) | |
| 55 | + | result.free(resultId2) | |
| 56 | + | end | |
| 57 | + | ||
| 58 | + | local stmtLen = string.len(stmt) | |
| 59 | + | if stmtLen > 102 then | |
| 60 | + | stmt = string.sub(stmt, 1, stmtLen - 1) | |
| 61 | + | db.query(stmt) | |
| 62 | + | end | |
| 63 | + | until not result.next(resultId) | |
| 64 | + | result.free(resultId) | |
| 65 | + | end | |
| 66 | + | ||
| 67 | + | -- Delete the inboxes | |
| 68 | + | db.query("DELETE FROM `player_depotitems` WHERE `itemtype` = 14404") | |
| 69 | + | return true | |
| 70 | + | end |
| @@ -0,0 +1,5 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 10 (stamina)") | |
| 3 | + | db.query("ALTER TABLE `players` ADD `stamina` SMALLINT UNSIGNED NOT NULL DEFAULT 2520") | |
| 4 | + | return true | |
| 5 | + | end |
| @@ -0,0 +1,28 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 11 (improved guild and players online structure)") | |
| 3 | + | db.query("CREATE TABLE IF NOT EXISTS `guild_membership` (`player_id` int(11) NOT NULL, `guild_id` int(11) NOT NULL, `rank_id` int(11) NOT NULL, `nick` varchar(15) NOT NULL DEFAULT '', PRIMARY KEY (`player_id`), KEY `guild_id` (`guild_id`), KEY `rank_id` (`rank_id`)) ENGINE=InnoDB") | |
| 4 | + | db.query("ALTER TABLE `guild_membership` ADD CONSTRAINT `guild_membership_ibfk_3` FOREIGN KEY (`rank_id`) REFERENCES `guild_ranks` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `guild_membership_ibfk_1` FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `guild_membership_ibfk_2` FOREIGN KEY (`guild_id`) REFERENCES `guilds` (`id`) ON DELETE CASCADE ON UPDATE CASCADE") | |
| 5 | + | db.query("ALTER TABLE `guild_invites` ADD PRIMARY KEY (`player_id`, `guild_id`)") | |
| 6 | + | db.query("ALTER TABLE `player_skills` ADD PRIMARY KEY (`player_id`, `skillid`)") | |
| 7 | + | db.query("ALTER TABLE `player_storage` ADD PRIMARY KEY (`player_id`, `key`)") | |
| 8 | + | ||
| 9 | + | local resultId = db.storeQuery("SELECT `players`.`id` AS `player_id`, `players`.`rank_id` AS `rank_id`, `players`.`guildnick` AS `guild_nick`, `guild_ranks`.`guild_id` AS `guild_id` FROM `guild_ranks` INNER JOIN `players` ON `guild_ranks`.`id` = `players`.`rank_id`") | |
| 10 | + | if resultId ~= false then | |
| 11 | + | local stmt = "INSERT INTO `guild_membership` (`player_id`, `guild_id`, `rank_id`, `nick`) VALUES " | |
| 12 | + | repeat | |
| 13 | + | stmt = stmt .. "(" .. result.getNumber(resultId, "player_id") .. "," .. result.getNumber(resultId, "guild_id") .. "," .. result.getNumber(resultId, "rank_id") .. "," .. db.escapeString(result.getString(resultId, "guild_nick")) .. ")," | |
| 14 | + | until not result.next(resultId) | |
| 15 | + | result.free(resultId) | |
| 16 | + | ||
| 17 | + | local stmtLen = string.len(stmt) | |
| 18 | + | if stmtLen > 83 then | |
| 19 | + | stmt = string.sub(stmt, 1, stmtLen - 1) | |
| 20 | + | db.query(stmt) | |
| 21 | + | end | |
| 22 | + | end | |
| 23 | + | ||
| 24 | + | db.query("ALTER TABLE `players` DROP `rank_id`, DROP `guildnick`, DROP `direction`, DROP `loss_experience`, DROP `loss_mana`, DROP `loss_skills`, DROP `premend`, DROP `online`") | |
| 25 | + | db.query("DROP TRIGGER IF EXISTS `ondelete_guilds`") | |
| 26 | + | db.query("CREATE TABLE IF NOT EXISTS `players_online` (`player_id` int(11) NOT NULL, PRIMARY KEY (`player_id`)) ENGINE=MEMORY") | |
| 27 | + | return true | |
| 28 | + | end |
| @@ -0,0 +1,24 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 12 (storing players record and message of the day in database)") | |
| 3 | + | ||
| 4 | + | local motdNum = "" | |
| 5 | + | local motd = "" | |
| 6 | + | ||
| 7 | + | local lastMotdFile = io.open("lastMotd.txt", "r") | |
| 8 | + | if lastMotdFile then | |
| 9 | + | motdNum = lastMotdFile:read() | |
| 10 | + | motd = lastMotdFile:read() | |
| 11 | + | lastMotdFile:close() | |
| 12 | + | end | |
| 13 | + | ||
| 14 | + | local record = 0 | |
| 15 | + | ||
| 16 | + | local playersRecordFile = io.open("playersRecord.txt", "r") | |
| 17 | + | if playersRecordFile then | |
| 18 | + | record = playersRecordFile:read("*n") | |
| 19 | + | playersRecordFile:close() | |
| 20 | + | end | |
| 21 | + | ||
| 22 | + | db.query("INSERT INTO `server_config` (`config`, `value`) VALUES ('players_record', '" .. record .. "'), ('motd_hash', SHA1(" .. db.escapeString(motd) .. ")), ('motd_num', " .. db.escapeString(motdNum) .. ")") | |
| 23 | + | return true | |
| 24 | + | end |
| @@ -0,0 +1,9 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 13 (house bidding system and additional columns to other tables)") | |
| 3 | + | ||
| 4 | + | db.query("ALTER TABLE `player_deaths` ADD `mostdamage_by` varchar(100) NOT NULL, ADD `mostdamage_is_player` tinyint(1) NOT NULL DEFAULT '0', ADD `unjustified` tinyint(1) NOT NULL DEFAULT '0', ADD `mostdamage_unjustified` tinyint(1) NOT NULL DEFAULT '0', ADD KEY `killed_by` (`killed_by`), ADD KEY `mostdamage_by` (`mostdamage_by`)") | |
| 5 | + | db.query("ALTER TABLE `houses` ADD `name` varchar(255) NOT NULL, ADD `rent` int(11) NOT NULL DEFAULT '0', ADD `town_id` int(11) NOT NULL DEFAULT '0', ADD `bid` int(11) NOT NULL DEFAULT '0', ADD `bid_end` int(11) NOT NULL DEFAULT '0', ADD `last_bid` int(11) NOT NULL DEFAULT '0', ADD `highest_bidder` int(11) NOT NULL DEFAULT '0', ADD `size` int(11) NOT NULL DEFAULT '0', ADD `beds` int(11) NOT NULL DEFAULT '0', ADD KEY `owner` (`owner`), ADD KEY `town_id` (`town_id`)") | |
| 6 | + | db.query("ALTER TABLE `players` ADD `onlinetime` int(11) NOT NULL DEFAULT '0', ADD `deletion` bigint(15) NOT NULL DEFAULT '0'") | |
| 7 | + | db.query("ALTER TABLE `accounts` ADD `points` int(11) NOT NULL DEFAULT '0', ADD `creation` int(11) NOT NULL DEFAULT '0'") | |
| 8 | + | return true | |
| 9 | + | end |
| @@ -0,0 +1,37 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 14 (account_bans, ip_bans and player_bans)") | |
| 3 | + | ||
| 4 | + | db.query("CREATE TABLE IF NOT EXISTS `account_bans` (`account_id` int(11) NOT NULL, `reason` varchar(255) NOT NULL, `banned_at` bigint(20) NOT NULL, `expires_at` bigint(20) NOT NULL, `banned_by` int(11) NOT NULL, PRIMARY KEY (`account_id`), KEY `banned_by` (`banned_by`), FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB") | |
| 5 | + | db.query("CREATE TABLE IF NOT EXISTS `account_ban_history` (`account_id` int(11) NOT NULL, `reason` varchar(255) NOT NULL, `banned_at` bigint(20) NOT NULL, `expired_at` bigint(20) NOT NULL, `banned_by` int(11) NOT NULL, PRIMARY KEY (`account_id`), KEY `banned_by` (`banned_by`), FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB") | |
| 6 | + | db.query("CREATE TABLE IF NOT EXISTS `ip_bans` (`ip` int(10) unsigned NOT NULL, `reason` varchar(255) NOT NULL, `banned_at` bigint(20) NOT NULL, `expires_at` bigint(20) NOT NULL, `banned_by` int(11) NOT NULL, PRIMARY KEY (`ip`), KEY `banned_by` (`banned_by`), FOREIGN KEY (`banned_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB") | |
| 7 | + | db.query("CREATE TABLE IF NOT EXISTS `player_namelocks` (`player_id` int(11) NOT NULL, `reason` varchar(255) NOT NULL, `namelocked_at` bigint(20) NOT NULL, `namelocked_by` int(11) NOT NULL, PRIMARY KEY (`player_id`), KEY `namelocked_by` (`namelocked_by`), FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (`namelocked_by`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB") | |
| 8 | + | ||
| 9 | + | local resultId = db.storeQuery("SELECT `player`, `time` FROM `bans` WHERE `type` = 2") | |
| 10 | + | if resultId ~= false then | |
| 11 | + | local stmt = "INSERT INTO `player_namelocks` (`player_id`, `namelocked_at`, `namelocked_by`) VALUES " | |
| 12 | + | repeat | |
| 13 | + | stmt = stmt .. "(" .. result.getNumber(resultId, "player") .. "," .. result.getNumber(resultId, "time") .. "," .. result.getNumber(resultId, "player") .. ")," | |
| 14 | + | until not result.next(resultId) | |
| 15 | + | result.free(resultId) | |
| 16 | + | ||
| 17 | + | local stmtLen = string.len(stmt) | |
| 18 | + | if stmtLen > 86 then | |
| 19 | + | stmt = string.sub(stmt, 1, stmtLen - 1) | |
| 20 | + | db.query(stmt) | |
| 21 | + | end | |
| 22 | + | end | |
| 23 | + | ||
| 24 | + | db.query("DROP TRIGGER `ondelete_accounts`") | |
| 25 | + | db.query("DROP TRIGGER `ondelete_players`") | |
| 26 | + | db.query("ALTER TABLE `accounts` DROP `warnings`") | |
| 27 | + | ||
| 28 | + | db.query("DROP TABLE `bans`") | |
| 29 | + | ||
| 30 | + | print("Run this query in your database to create the ondelete_players trigger:") | |
| 31 | + | print("DELIMITER //") | |
| 32 | + | print("CREATE TRIGGER `ondelete_players` BEFORE DELETE ON `players`") | |
| 33 | + | print(" FOR EACH ROW BEGIN") | |
| 34 | + | print(" UPDATE `houses` SET `owner` = 0 WHERE `owner` = OLD.`id`;") | |
| 35 | + | print("END //") | |
| 36 | + | return true | |
| 37 | + | end |
| @@ -0,0 +1,30 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 15 (moving groups to data/XML/groups.xml)") | |
| 3 | + | ||
| 4 | + | db.query("ALTER TABLE players DROP FOREIGN KEY players_ibfk_2") | |
| 5 | + | db.query("DROP INDEX group_id ON players") | |
| 6 | + | ||
| 7 | + | db.query("ALTER TABLE accounts DROP FOREIGN KEY accounts_ibfk_1") | |
| 8 | + | db.query("DROP INDEX group_id ON accounts") | |
| 9 | + | db.query("ALTER TABLE `accounts` DROP `group_id`") | |
| 10 | + | ||
| 11 | + | local groupsFile = io.open("data/XML/groups.xml", "w") | |
| 12 | + | if groupsFile then | |
| 13 | + | groupsFile:write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n") | |
| 14 | + | groupsFile:write("<groups>\r\n") | |
| 15 | + | ||
| 16 | + | local resultId = db.storeQuery("SELECT `id`, `name`, `flags`, `access`, `maxdepotitems`, `maxviplist` FROM `groups` ORDER BY `id` ASC") | |
| 17 | + | if resultId ~= false then | |
| 18 | + | repeat | |
| 19 | + | groupsFile:write("\t<group id=\"" .. result.getNumber(resultId, "id") .. "\" name=\"" .. result.getString(resultId, "name") .. "\" flags=\"" .. string.format("%u", result.getNumber(resultId, "flags")) .. "\" access=\"" .. result.getNumber(resultId, "access") .. "\" maxdepotitems=\"" .. result.getNumber(resultId, "maxdepotitems") .. "\" maxvipentries=\"" .. result.getNumber(resultId, "maxviplist") .. "\" />\r\n") | |
| 20 | + | until not result.next(resultId) | |
| 21 | + | result.free(resultId) | |
| 22 | + | end | |
| 23 | + | ||
| 24 | + | groupsFile:write("</groups>\r\n") | |
| 25 | + | groupsFile:close() | |
| 26 | + | ||
| 27 | + | db.query("DROP TABLE `groups`") | |
| 28 | + | end | |
| 29 | + | return true | |
| 30 | + | end |
| @@ -0,0 +1,8 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 16 (moving skills into players table)") | |
| 3 | + | db.query("ALTER TABLE `players` ADD `skill_fist` int(10) unsigned NOT NULL DEFAULT 10, ADD `skill_fist_tries` bigint(20) unsigned NOT NULL DEFAULT 0, ADD `skill_club` int(10) unsigned NOT NULL DEFAULT 10, ADD `skill_club_tries` bigint(20) unsigned NOT NULL DEFAULT 0, ADD `skill_sword` int(10) unsigned NOT NULL DEFAULT 10, ADD `skill_sword_tries` bigint(20) unsigned NOT NULL DEFAULT 0, ADD `skill_axe` int(10) unsigned NOT NULL DEFAULT 10, ADD `skill_axe_tries` bigint(20) unsigned NOT NULL DEFAULT 0, ADD `skill_dist` int(10) unsigned NOT NULL DEFAULT 10, ADD `skill_dist_tries` bigint(20) unsigned NOT NULL DEFAULT 0, ADD `skill_shielding` int(10) unsigned NOT NULL DEFAULT 10, ADD `skill_shielding_tries` bigint(20) unsigned NOT NULL DEFAULT 0, ADD `skill_fishing` int(10) unsigned NOT NULL DEFAULT 10, ADD `skill_fishing_tries` bigint(20) unsigned NOT NULL DEFAULT 0") | |
| 4 | + | db.query("UPDATE `players` SET `skill_fist` = (SELECT `value` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 0), `skill_fist_tries` = (SELECT `count` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 0), `skill_club` = (SELECT `value` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 1), `skill_club_tries` = (SELECT `count` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 1), `skill_sword` = (SELECT `value` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 2), `skill_sword_tries` = (SELECT `count` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 2), `skill_axe` = (SELECT `value` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 3), `skill_axe_tries` = (SELECT `count` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 3), `skill_dist` = (SELECT `value` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 4), `skill_dist_tries` = (SELECT `count` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 4), `skill_shielding` = (SELECT `value` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 5), `skill_shielding_tries` = (SELECT `count` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 5), `skill_fishing` = (SELECT `value` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 6), `skill_fishing_tries` = (SELECT `count` FROM `player_skills` WHERE `player_id` = `id` AND `skillid` = 6)") | |
| 5 | + | db.query("DROP TRIGGER `oncreate_players`") | |
| 6 | + | db.query("DROP TABLE `player_skills`") | |
| 7 | + | return true | |
| 8 | + | end |
| @@ -0,0 +1,9 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 17 (fixing primary key in account ban history)") | |
| 3 | + | db.query("ALTER TABLE `account_ban_history` DROP FOREIGN KEY `account_ban_history_ibfk_1`") | |
| 4 | + | db.query("ALTER TABLE `account_ban_history` DROP PRIMARY KEY") | |
| 5 | + | db.query("ALTER TABLE `account_ban_history` ADD `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST") | |
| 6 | + | db.query("ALTER TABLE `account_ban_history` ADD INDEX (`account_id`)") | |
| 7 | + | db.query("ALTER TABLE `account_ban_history` ADD FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE") | |
| 8 | + | return true | |
| 9 | + | end |
| @@ -0,0 +1,6 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 18 (optimize account password field)") | |
| 3 | + | db.query("DELETE FROM `server_config` WHERE `config` = 'encryption'") | |
| 4 | + | db.query("ALTER TABLE `accounts` CHANGE `password` `password` CHAR(40) NOT NULL") | |
| 5 | + | return true | |
| 6 | + | end |
| @@ -0,0 +1,5 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 19 (authenticator token support)") | |
| 3 | + | db.query("ALTER TABLE `accounts` ADD COLUMN `secret` CHAR(16) NULL AFTER `password`") | |
| 4 | + | return true | |
| 5 | + | end |
| @@ -0,0 +1,5 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 20 (setting default cap to 400)") | |
| 3 | + | db.query("ALTER TABLE `players` CHANGE `cap` `cap` int(11) NOT NULL DEFAULT '400'") | |
| 4 | + | return true | |
| 5 | + | end |
| @@ -0,0 +1,6 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 21 (store towns in database)") | |
| 3 | + | db.query("CREATE TABLE IF NOT EXISTS `towns` (`id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `posx` int(11) NOT NULL DEFAULT '0', `posy` int(11) NOT NULL DEFAULT '0', `posz` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`)) ENGINE=InnoDB") | |
| 4 | + | ||
| 5 | + | return true | |
| 6 | + | end |
| @@ -0,0 +1,32 @@ | |||
| 1 | + | function onUpdateDatabase() | |
| 2 | + | print("> Updating database to version 22 (UTF-8 encoding)") | |
| 3 | + | db.query("ALTER TABLE account_ban_history CONVERT TO CHARACTER SET utf8") | |
| 4 | + | db.query("ALTER TABLE account_bans CONVERT TO CHARACTER SET utf8") | |
| 5 | + | db.query("ALTER TABLE account_viplist CONVERT TO CHARACTER SET utf8") | |
| 6 | + | db.query("ALTER TABLE accounts CONVERT TO CHARACTER SET utf8") | |
| 7 | + | db.query("ALTER TABLE guild_invites CONVERT TO CHARACTER SET utf8") | |
| 8 | + | db.query("ALTER TABLE guild_membership CONVERT TO CHARACTER SET utf8") | |
| 9 | + | db.query("ALTER TABLE guild_ranks CONVERT TO CHARACTER SET utf8") | |
| 10 | + | db.query("ALTER TABLE guild_wars CONVERT TO CHARACTER SET utf8") | |
| 11 | + | db.query("ALTER TABLE guilds CONVERT TO CHARACTER SET utf8") | |
| 12 | + | db.query("ALTER TABLE guildwar_kills CONVERT TO CHARACTER SET utf8") | |
| 13 | + | db.query("ALTER TABLE house_lists CONVERT TO CHARACTER SET utf8") | |
| 14 | + | db.query("ALTER TABLE houses CONVERT TO CHARACTER SET utf8") | |
| 15 | + | db.query("ALTER TABLE ip_bans CONVERT TO CHARACTER SET utf8") | |
| 16 | + | db.query("ALTER TABLE market_history CONVERT TO CHARACTER SET utf8") | |
| 17 | + | db.query("ALTER TABLE market_offers CONVERT TO CHARACTER SET utf8") | |
| 18 | + | db.query("ALTER TABLE player_deaths CONVERT TO CHARACTER SET utf8") | |
| 19 | + | db.query("ALTER TABLE player_depotitems CONVERT TO CHARACTER SET utf8") | |
| 20 | + | db.query("ALTER TABLE player_inboxitems CONVERT TO CHARACTER SET utf8") | |
| 21 | + | db.query("ALTER TABLE player_items CONVERT TO CHARACTER SET utf8") | |
| 22 | + | db.query("ALTER TABLE player_namelocks CONVERT TO CHARACTER SET utf8") | |
| 23 | + | db.query("ALTER TABLE player_spells CONVERT TO CHARACTER SET utf8") | |
| 24 | + | db.query("ALTER TABLE player_storage CONVERT TO CHARACTER SET utf8") | |
| 25 | + | db.query("ALTER TABLE players CONVERT TO CHARACTER SET utf8") | |
| 26 | + | db.query("ALTER TABLE players_online CONVERT TO CHARACTER SET utf8") | |
| 27 | + | db.query("ALTER TABLE server_config CONVERT TO CHARACTER SET utf8") | |
| 28 | + | db.query("ALTER TABLE tile_store CONVERT TO CHARACTER SET utf8") | |
| 29 | + | db.query("ALTER TABLE towns CONVERT TO CHARACTER SET utf8") | |
| 30 | + | ||
| 31 | + | return true | |
| 32 | + | end |