Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: multiworld system #2826

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0169d73
feat: multiworld system
phacUFPE Aug 17, 2024
38e939e
fix: small fixes
phacUFPE Aug 17, 2024
b2c524c
Code format - (Clang-format)
github-actions[bot] Aug 17, 2024
269954a
fix: missing sql modifications
phacUFPE Aug 18, 2024
675d2e1
feat: added migrations and schema updated
phacUFPE Aug 18, 2024
bbde1a1
Code format - (Clang-format)
github-actions[bot] Aug 18, 2024
6918a5d
feat: login protocol bytes
phacUFPE Aug 18, 2024
d14d0a1
fix: fixes
phacUFPE Aug 18, 2024
f3bfba9
fix: migration
phacUFPE Aug 18, 2024
1c2ced7
fix: removed gameworld xml
phacUFPE Aug 18, 2024
bdea03c
fix: remove comma
phacUFPE Aug 18, 2024
1f68767
refactor: worlds instantiated by game
phacUFPE Aug 18, 2024
f2986c0
fix: schema
phacUFPE Aug 18, 2024
5bdabae
fix: build failing
phacUFPE Aug 18, 2024
3e12f90
fix: default worldId
phacUFPE Aug 18, 2024
0892bce
feat: load worlds on canary server startup and configure this world
phacUFPE Aug 19, 2024
c41ed24
fix: schema and migrations
phacUFPE Aug 19, 2024
6f119b4
fix: prevent mailbox between worlds
phacUFPE Aug 19, 2024
4b50a06
fix: added missing semicolon
phacUFPE Aug 19, 2024
0f76aa1
fix: update database to load only players from this world
phacUFPE Aug 19, 2024
48ce8c9
fix: highscores by worlds
phacUFPE Aug 19, 2024
0734aed
Code format - (Clang-format)
github-actions[bot] Aug 19, 2024
f1938fc
fix: migration
phacUFPE Aug 19, 2024
dd14a1e
fix: database migrations and schema
phacUFPE Aug 20, 2024
e7a2bb8
Lua code format - (Stylua)
github-actions[bot] Aug 20, 2024
d1fdeaa
fix: suggestions
phacUFPE Aug 22, 2024
cba01f7
fix: hirelings spawn
phacUFPE Aug 26, 2024
33a2407
fix: use snake case on new column to keep pattern
phacUFPE Aug 26, 2024
c039f56
hireling: fix query column name.
elsongabriel Aug 26, 2024
aa36b85
fix: tests
phacUFPE Aug 27, 2024
91e075f
fix: missing guilds world id migration
phacUFPE Aug 28, 2024
11994ab
multiworld system: refactoring of world data. changed and improved ch…
elsongabriel Aug 30, 2024
f505967
schema: fix `creation` column.
elsongabriel Aug 30, 2024
fa37590
multiworld system: refactoring of world data.
elsongabriel Aug 30, 2024
0c08070
multiworld system: adding status port to world table. adjusting cruci…
elsongabriel Sep 6, 2024
c2717b8
Merge branch 'main' into phacUFPE/multiworld_system
elsongabriel Sep 6, 2024
d3ef451
Merge branch 'main' into phacUFPE/multiworld_system
elsongabriel Sep 12, 2024
1d3a971
Merge branch 'main' into phacUFPE/multiworld_system
phacUFPE Sep 24, 2024
6402b46
Merge branch 'main' into phacUFPE/multiworld_system
elsongabriel Sep 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ toggleMaintainMode = false
maintainModeMessage = ""

-- Combat settings
-- NOTE: valid values for worldType are: "pvp", "no-pvp" and "pvp-enforced"
-- NOTE: removeBeginningWeaponAmmunition: spears, arrows, bolt have endless ammo (allows training for paladins)
-- NOTE: refundManaOnBeginningWeapons: wand of vortex and snakebite refund mana used (allows training for mages)
worldType = "pvp"
hotkeyAimbotEnabled = true
protectionLevel = 7
pzLocked = 60 * 1000
Expand All @@ -52,14 +50,17 @@ cleanProtectionZones = false
-- Connection Config
-- NOTE: allowOldProtocol can allow login on 10x protocol. (11.00)
-- NOTE: maxPlayers set to 0 means no limit
-- NOTE: MaxPacketsPerSeconds if you change you will be subject to bugs by WPE, keep the default value of 25,
-- NOTE: gameProtocolPort and statusProtocolPort configs are deprecated, now will be loaded from database, statusProtocolPort will be ever as 9PORT, example: 97172
-- NOTE: serverName is different from world name, but for better usage, use the same name as world name
-- NOTE: serverMotd is deprecated, now will be loaded from database
-- NOTE: MaxPacketsPerSeconds if you change you will be subject to bugs by WPE, keep the default value of 25,
-- It's recommended to use a range like min 50 in this function, otherwise you will be disconnected after equipping two-handed distance weapons.
ip = "127.0.0.1"
allowOldProtocol = false
bindOnlyGlobalAddress = false
loginProtocolPort = 7171
gameProtocolPort = 7172
statusProtocolPort = 7171
statusProtocolPort = 97172
maxPlayers = 0
serverName = "OTServBR-Global"
serverMotd = "Welcome to the OTServBR-Global!"
Expand All @@ -71,6 +72,14 @@ maxContainer = 100
maxPlayersOnlinePerAccount = 1
maxPlayersOutsidePZPerAccount = 1

-- World settings (This information will be loaded from the 'worlds' database table as well)
-- NOTE: World id is 1 as default, new worlds must have different ids always greater than 1
-- NOTE: valid values for worldType are: "pvp", "no-pvp", "pvp-enforced", "retro-pvp" and "retro-pvp-enforced"
-- NOTE: valid values for worldLocation are: "Europe", "North America", "South America" and "Oceania"
worldId = 1
worldType = "pvp"
worldLocation = "South America"

-- Packet Compression
-- Minimize network bandwith and reduce ping
-- Levels: 0 = disabled, 1 = best speed, 9 = best compression
Expand Down Expand Up @@ -244,7 +253,6 @@ onlyPremiumAccount = false
-- NOTE: autoBank = true, the dropped coins from monsters will be automatically deposited to your bank account.
-- NOTE: toggleGoldPouchAllowAnything will allow players to move items or gold to gold pouch
-- NOTE: toggleGoldPouchQuickLootOnly will ONLY allow quickloot to move items to gold pouch
-- NOTE: toggleServerIsRetroPVP will make this server as retro, setting PARTY_PROTECTION and ADVANCED_SECURE_MODE to 0
-- NOTE: toggleTravelsFree will make all travels from boat free
-- NOTE: buyAolCommandFee will add fee when player buy aol by command (!aol), active changing value more than 0 (fee value. ex: 1 = 1gp aol will be 50001)
-- NOTE: buyBlessCommandFee will add fee when player buy bless by command (!bless), active changing value between 1 and 100 (fee percent. ex: 3 = 3%, 30 = 30%)
Expand All @@ -263,7 +271,6 @@ autoLoot = false
autoBank = false
toggleGoldPouchAllowAnything = false
toggleGoldPouchQuickLootOnly = false
toggleServerIsRetroPVP = false
toggleTravelsFree = false
buyAolCommandFee = 0
buyBlessCommandFee = 0
Expand Down Expand Up @@ -539,7 +546,6 @@ startupDatabaseOptimization = true
ownerName = "OpenTibiaBR"
ownerEmail = "[email protected]"
url = "http://docs.opentibiabr.com/"
location = "South America"

-- Sends Discord webhook notifications on startup, raids and shutdown.
-- The URL layout is https://discord.com/api/webhooks/:id/:token
Expand Down
72 changes: 71 additions & 1 deletion data-otservbr-global/migrations/46.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,73 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
logger.info("Updating database to version 47 (multiworld system)")

db.query("SET FOREIGN_KEY_CHECKS=0;")

db.query([[
CREATE TABLE IF NOT EXISTS `worlds` (
`id` int(3) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(80) NOT NULL,
`type` enum('no-pvp','pvp','retro-pvp','pvp-enforced','retro-pvp-enforced') NOT NULL,
`motd` varchar(255) NOT NULL DEFAULT '',
`location` enum('Europe','North America','South America','Oceania') NOT NULL,
`ip` varchar(15) NOT NULL,
`port` int(5) UNSIGNED NOT NULL,
`port_status` int(6) UNSIGNED NOT NULL,
`creation` int(11) NOT NULL DEFAULT 0,
CONSTRAINT `worlds_pk` PRIMARY KEY (`id`),
CONSTRAINT `worlds_unique` UNIQUE (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
]])

db.query("ALTER TABLE `server_config` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `server_config` DROP PRIMARY KEY;")
db.query("ALTER TABLE `server_config` ADD PRIMARY KEY (`config`, `world_id`);")
db.query("ALTER TABLE `server_config` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `players_online` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `players_online` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `players` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `players` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `guilds` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `guilds` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `houses` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `houses` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `house_lists` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `house_lists` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `account_viplist` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `account_viplist` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `tile_store` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `tile_store` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `market_offers` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `market_offers` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `market_history` ADD `world_id` int(3) UNSIGNED NOT NULL DEFAULT 1;")
db.query("ALTER TABLE `market_history` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("ALTER TABLE `server_config` DROP PRIMARY KEY")
db.query("ALTER TABLE `server_config` ADD PRIMARY KEY (`world_id`, `config`);")

db.query("ALTER TABLE `houses` CHANGE `id` `id` INT(11) NOT NULL;")
db.query("ALTER TABLE `houses` DROP PRIMARY KEY;")
db.query("ALTER TABLE `houses` ADD PRIMARY KEY (`id`, `world_id`);")
db.query("ALTER TABLE `houses` CHANGE `id` `id` INT(11) NOT NULL AUTO_INCREMENT;")
db.query("ALTER TABLE `houses` ADD FOREIGN KEY (`world_id`) REFERENCES `worlds` (`id`) ON DELETE CASCADE;")

db.query("DROP TRIGGER `ondelete_players`;")
db.query([[
CREATE TRIGGER `ondelete_players` BEFORE DELETE ON `players` FOR EACH ROW BEGIN
UPDATE `houses` SET `owner` = 0 WHERE `owner` = OLD.`id` AND `world_id` = OLD.`world_id`;
END;
]])

db.query("SET FOREIGN_KEY_CHECKS=1;")

return true
end
3 changes: 3 additions & 0 deletions data-otservbr-global/migrations/47.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
end
22 changes: 12 additions & 10 deletions data/XML/events.xml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<events>
<event name="Otservbr example 1" startdate="11/03/2020" enddate="12/30/2023" script="example.lua" >
<ingame exprate="100" lootrate="100" bosslootrate="100" spawnrate="100" skillrate="100" />
<description description="Otserver br example 1 description double exp and a half, double loot !chance!, regular spawn and double skill" />
<colors colordark="#235c00" colorlight="#2d7400" />
<details displaypriority="6" isseasonal="0" specialevent="0" />
<event name="Otservbr example 1" startdate="01/01/2024" enddate="12/31/2024">
<ingame exprate="100" lootrate="100" bosslootrate="100" spawnrate="100" skillrate="100"/>
<description
description="Otserver br example 1 description double exp and a half, double loot !chance!, regular spawn and double skill"/>
<colors colordark="#235c00" colorlight="#2d7400"/>
<details displaypriority="6" isseasonal="0" specialevent="0"/>
</event>
<event name="Otservbr example 2" startdate="2/2/2022" enddate="12/31/2023" script="" >
<ingame exprate="100" lootrate="100" bosslootrate="100" spawnrate="100" skillrate="100" />
<description description="Otserver br example 2 description 50% less exp, triple loot !chance!, 50% faster spawn and regular skill" />
<colors colordark="#735D10" colorlight="#8B6D05" />
<details displaypriority="6" isseasonal="0" specialevent="0" />
<event name="Otservbr example 2" startdate="01/01/2024" enddate="12/31/2024" script="">
<ingame exprate="100" lootrate="100" bosslootrate="100" spawnrate="100" skillrate="100"/>
<description
description="Otserver br example 2 description 50% less exp, triple loot !chance!, 50% faster spawn and regular skill"/>
<colors colordark="#735D10" colorlight="#8B6D05"/>
<details displaypriority="6" isseasonal="0" specialevent="0"/>
</event>
</events>
4 changes: 2 additions & 2 deletions data/events/scripts/creature.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function Creature:onTargetCombat(target)
return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE
end

if not IsRetroPVP() or PARTY_PROTECTION ~= 0 then
if not IsRetroPVP() then
if self:isPlayer() and target:isPlayer() then
local party = self:getParty()
if party then
Expand All @@ -71,7 +71,7 @@ function Creature:onTargetCombat(target)
end
end

if not IsRetroPVP() or ADVANCED_SECURE_MODE ~= 0 then
if not IsRetroPVP() then
if self:isPlayer() and target:isPlayer() then
if self:hasSecureMode() then
return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER
Expand Down
23 changes: 18 additions & 5 deletions data/global.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,31 @@ function IsRunningGlobalDatapack()
end
end

function getWorldTypeName()
local worldType = Game.getWorldType()
if worldType == WORLD_TYPE_PVP then
return "Open PvP"
elseif worldType == WORLD_TYPE_NO_PVP then
return "Optional PvP"
elseif worldType == WORLD_TYPE_PVP_ENFORCED then
return "Hardcore PvP"
elseif worldType == WORLD_TYPE_RETRO_PVP then
return "Retro Open PvP"
elseif worldType == WORLD_TYPE_RETRO_PVP_ENFORCED then
return "Retro Hardcore PvP"
else
return "Unknown"
end
end

function IsRetroPVP()
return configManager.getBoolean(configKeys.TOGGLE_SERVER_IS_RETRO)
return table.contains({ WORLD_TYPE_RETRO_PVP, WORLD_TYPE_RETRO_PVP_ENFORCED }, Game.getWorldType())
end

function IsTravelFree()
return configManager.getBoolean(configKeys.TOGGLE_TRAVELS_FREE)
end

-- NOTE: 0 is disabled.
PARTY_PROTECTION = (IsRetroPVP() and 0) or 1
ADVANCED_SECURE_MODE = (IsRetroPVP() and 0) or 1

NORTH = DIRECTION_NORTH
EAST = DIRECTION_EAST
SOUTH = DIRECTION_SOUTH
Expand Down
2 changes: 0 additions & 2 deletions data/libs/compat/compat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1461,8 +1461,6 @@ function setGlobalStorageValue(key, value)
return true
end

getWorldType = Game.getWorldType

numberToVariant = Variant
stringToVariant = Variant
positionToVariant = Variant
Expand Down
3 changes: 2 additions & 1 deletion data/libs/systems/hireling.lua
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,8 @@ function GetHirelingOutfitNameById(id)
end

function HirelingsInit()
local rows = db.storeQuery("SELECT * FROM `player_hirelings`")
local query = string.format("SELECT `ph`.* FROM `player_hirelings` AS `ph` INNER JOIN `players` as `p` ON `p`.`id` = `ph`.`player_id` WHERE `p`.`world_id` = %d", configManager.getNumber(configKeys.WORLD_ID))
local rows = db.storeQuery(query)
if rows then
local player_id, hireling
repeat
Expand Down
2 changes: 1 addition & 1 deletion data/modules/scripts/blessings/blessings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Blessings.Credits = {

Blessings.Config = {
AdventurerBlessingLevel = configManager.getNumber(configKeys.ADVENTURERSBLESSING_LEVEL), -- Free full bless until level
HasToF = not configManager.getBoolean(configKeys.TOGGLE_SERVER_IS_RETRO), -- Enables/disables twist of fate
HasToF = not IsRetroPVP(), -- Enables/disables twist of fate
InquisitonBlessPriceMultiplier = 1.1, -- Bless price multiplied by henricus
SkulledDeathLoseStoreItem = configManager.getBoolean(configKeys.SKULLED_DEATH_LOSE_STORE_ITEM), -- Destroy all items on store when dying with red/blackskull
InventoryGlowOnFiveBless = configManager.getBoolean(configKeys.INVENTORY_GLOW), -- Glow in yellow inventory items when the player has 5 or more bless,
Expand Down
7 changes: 1 addition & 6 deletions data/scripts/runes/magic_wall.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ function onCreateMagicWall(creature, position)
if tile and tile:getTopCreature() and not tile:getTopCreature():isPlayer() then
return false
end
local magicWall
if Game.getWorldType() == WORLD_TYPE_NO_PVP then
magicWall = ITEM_MAGICWALL_SAFE
else
magicWall = ITEM_MAGICWALL
end
local magicWall = Game.getWorldType() == WORLD_TYPE_NO_PVP and ITEM_MAGICWALL_SAFE or ITEM_MAGICWALL
local item = Game.createItem(magicWall, 1, position)
item:setDuration(16, 24)
end
Expand Down
7 changes: 1 addition & 6 deletions data/scripts/runes/wild_growth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ function onCreateWildGrowth(creature, position)
if tile and tile:getTopCreature() and not tile:getTopCreature():isPlayer() then
return false
end
local wildGrowth
if Game.getWorldType() == WORLD_TYPE_NO_PVP then
wildGrowth = ITEM_WILDGROWTH_SAFE
else
wildGrowth = ITEM_WILDGROWTH
end
local wildGrowth = Game.getWorldType() == WORLD_TYPE_NO_PVP and ITEM_WILDGROWTH_SAFE or ITEM_WILDGROWTH
local item = Game.createItem(wildGrowth, 1, position)
item:setDuration(30, 60)
end
Expand Down
2 changes: 1 addition & 1 deletion data/scripts/talkactions/player/server_info.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function serverInfo.onSay(player, words, param)
.. "\nProtection level: "
.. configManager.getNumber(configKeys.PROTECTION_LEVEL)
.. "\nWorldType: "
.. configManager.getString(configKeys.WORLD_TYPE)
.. getWorldTypeName()
.. "\nKills/day to red skull: "
.. configManager.getNumber(configKeys.DAY_KILLS_TO_RED)
.. "\nKills/week to red skull: "
Expand Down
Loading
Loading