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

Move vip to lua #4823

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
4 changes: 1 addition & 3 deletions config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,8 @@ forceMonsterTypesOnLoad = true
cleanProtectionZones = false
checkDuplicateStorageKeys = false

-- VIP and Depot limits
-- Depot limits
-- NOTE: you can set custom limits per group in data/XML/groups.xml
vipFreeLimit = 20
vipPremiumLimit = 100
depotFreeLimit = 2000
depotPremiumLimit = 15000

Expand Down
22 changes: 11 additions & 11 deletions data/cpplinter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ DBTransaction = {}
---@field query fun(query: string): any
---@field storeQuery fun(query: string): any
---@field escapeString fun(value: string): string
---@field asyncQuery fun(query: string): boolean
---@field asyncQuery fun(query: string, callback?: function): boolean
db = {}

---@class result
---@field free fun(resultId: number)
---@field next fun(resultId: number): number
---@field getNumber fun(resultId: number, column: string): number
---@field getString fun(resultId: number, column: number): string
---@field getString fun(resultId: number, column: string): string
---@field getBoolean fun(resultId: number, column: number): boolean
---@field getStream fun(resultId: number, column: number): string
result = {}
Expand Down Expand Up @@ -289,7 +289,7 @@ Podium = {}
---@field isImmune fun(self: Creature): boolean
---@field canSee fun(self: Creature, position: Position): boolean
---@field canSeeCreature fun(self: Creature, creature: Creature): boolean
---@field canSeeGhostMode fun(self: Creature): boolean
---@field canSeeGhostMode fun(self: Creature, otherCreature?: Creature): boolean
---@field canSeeInvisibility fun(self: Creature): boolean
---@field getParent fun(self: Creature): Creature
---@field getId fun(self: Creature): number
Expand Down Expand Up @@ -2259,14 +2259,12 @@ configKeys = {
SERVER_SAVE_NOTIFY_DURATION = 34,
YELL_MINIMUM_LEVEL = 35,
MINIMUM_LEVEL_TO_SEND_PRIVATE = 36,
VIP_FREE_LIMIT = 37,
VIP_PREMIUM_LIMIT = 38,
DEPOT_FREE_LIMIT = 39,
DEPOT_PREMIUM_LIMIT = 40,
QUEST_TRACKER_FREE_LIMIT = 41,
QUEST_TRACKER_PREMIUM_LIMIT = 42,
STAMINA_REGEN_MINUTE = 43,
STAMINA_REGEN_PREMIUM = 44,
DEPOT_FREE_LIMIT = 37,
DEPOT_PREMIUM_LIMIT = 38,
QUEST_TRACKER_FREE_LIMIT = 39,
QUEST_TRACKER_PREMIUM_LIMIT = 40,
STAMINA_REGEN_MINUTE = 41,
STAMINA_REGEN_PREMIUM = 42,
}

ITEM_TYPE_NONE = 0
Expand Down Expand Up @@ -2465,3 +2463,5 @@ SPELLGROUP_ULTIMATESTRIKES = 8
WORLD_TYPE_NO_PVP = 1
WORLD_TYPE_PVP = 2
WORLD_TYPE_PVP_ENFORCED = 3

PLAYER_NAME_LENGTH = 25
5 changes: 5 additions & 0 deletions data/lib/core/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,8 @@ CYCLOPEDIA_SKILL_FIST = 11
CYCLOPEDIA_SKILL_FISHING = 13

CYCLOPEDIA_SKILL_AMOUNT = 8

VIPSTATUS_OFFLINE = 0
VIPSTATUS_ONLINE = 1
VIPSTATUS_PENDING = 2
VIPSTATUS_TRAINING = 3
1 change: 1 addition & 0 deletions data/lib/core/core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ dofile('data/lib/core/quests.lua')
dofile('data/lib/core/raids.lua')
dofile('data/lib/core/teleport.lua')
dofile('data/lib/core/tile.lua')
dofile('data/lib/core/vip.lua')
dofile('data/lib/core/town.lua')
dofile('data/lib/core/vocation.lua')
138 changes: 138 additions & 0 deletions data/lib/core/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -749,3 +749,141 @@ function Player.sendInboxItems(self, items, containerId)
end
container:moveTo(inbox)
end

function Player.getMaxVipEntries(self)
local groupMaxVipEntries = self:getGroup():getMaxVipEntries()
if groupMaxVipEntries > 0 then
return groupMaxVipEntries
end
return self:isPremium() and VIP_PREMIUM_LIMIT or VIP_FREE_LIMIT
end

function Player.addVip(self, name)
if name:len() > PLAYER_NAME_LENGTH then
return
end

local vipGuid
local vipName
local status

-- check if the Vip is online
local vipPlayer = Player(name)
if vipPlayer then
if vipPlayer:hasFlag(PlayerFlag_SpecialVIP) and not self:hasFlag(PlayerFlag_SpecialVIP) then
self:sendTextMessage(MESSAGE_STATUS_SMALL, "You can not add this player.")
return
end

vipGuid = vipPlayer:getGuid()
vipName = vipPlayer:getName()
status = (not vipPlayer:isInGhostMode() or self:canSeeGhostMode(vipPlayer)) and VIPSTATUS_ONLINE or VIPSTATUS_OFFLINE
else
-- if not online, attempt to load by name
local resultId = db.storeQuery("SELECT `name`, `id`, `group_id` FROM `players` WHERE `name` = " .. db.escapeString(name))
if not resultId then
self:sendTextMessage(MESSAGE_STATUS_SMALL, "A player with this name does not exist.")
return
end

-- find Vip group and check if exists
local groupId = result.getNumber(resultId, "group_id")
local group = Group(groupId)
if not group then
return
end

if group:hasFlag(PlayerFlag_SpecialVIP) and not self:hasFlag(PlayerFlag_SpecialVIP) then
self:sendTextMessage(MESSAGE_STATUS_SMALL, "You can not add this player.")
return
end

vipGuid = result.getNumber(resultId, "id")
vipName = result.getString(resultId, "name")
status = VIPSTATUS_OFFLINE
end

local playerVip = Vip(self:getGuid())
if not playerVip:canAdd() then
self:sendTextMessage(MESSAGE_STATUS_SMALL, "You cannot add more buddies.")
return
end

if playerVip:has(vipGuid) then
self:sendTextMessage(MESSAGE_STATUS_SMALL, "This player is already in your list.")
return
end

local description = ""
local icon = 0
local notify = false

playerVip:add(vipGuid)
self:sendVip(vipGuid, vipName, description, icon, notify, status)

local accountId = self:getAccountId()
db.asyncQuery("INSERT INTO `account_viplist` (`account_id`, `player_id`) VALUES (" .. accountId .. ", " .. vipGuid .. ")")
end

function Player.removeVip(self, vipGuid)
local playerVip = Vip(self:getGuid())
playerVip:remove(vipGuid)

local accountId = self:getAccountId()
db.asyncQuery("DELETE FROM `account_viplist` WHERE `account_id` = " .. accountId .. " AND `player_id` = " .. vipGuid)
end

function Player.editVip(self, vipGuid, description, icon, notify)
local playerVip = Vip(self:getGuid())
if not playerVip:has(vipGuid) then
return
end

local accountId = self:getAccountId()
db.asyncQuery("UPDATE `account_viplist` SET `description` = " .. db.escapeString(description) ..", `icon` = " .. icon .. ", `notify` = " .. (notify and 1 or 0) .. " WHERE `account_id` = " .. accountId .. " AND `player_id` = " .. vipGuid .. "")
end

function Player.notifyVipStatusChange(self, vipGuid, status)
local vipPlayer = Player(vipGuid)
if not vipPlayer then
return
end

local playerVip = Vip(self:getGuid())
if not playerVip:has(vipGuid) then
return
end

self:sendUpdatedVipStatus(vipGuid, status)

if status == VIPSTATUS_ONLINE then
self:sendTextMessage(MESSAGE_STATUS_SMALL, vipPlayer:getName() .. " has logged in.")
elseif status == VIPSTATUS_OFFLINE then
self:sendTextMessage(MESSAGE_STATUS_SMALL, vipPlayer:getName() .. " has logged out.")
end
end

function Player.sendVip(self, guid, name, description, icon, notify, status)
local msg = NetworkMessage()
msg:addByte(0xD2)
msg:addU32(guid)
msg:addString(name)
msg:addString(description)
msg:addU32(math.min(10, icon))
msg:addByte(notify and 1 or 0)
msg:addByte(status)
msg:addByte(0x00) -- vipGroups (placeholder)
msg:sendToPlayer(self)
msg:delete()
return true
end

function Player.sendUpdatedVipStatus(self, guid, status)
local msg = NetworkMessage()
msg:addByte(0xD3)
msg:addU32(guid)
msg:addByte(status)
msg:sendToPlayer(self)
msg:delete()
return true
end
53 changes: 53 additions & 0 deletions data/lib/core/vip.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
do
-- VIP limits
VIP_FREE_LIMIT = 20
VIP_PREMIUM_LIMIT = 100

Vips = {}

local function clear(self)
Vips[self.guid] = nil
end

local function getList(self)
return self.vips
end

local function add(self, vip)
self.vips[vip] = vip
end

local function remove(self, vip)
self.vips[vip] = nil
end

local function has(self, vip)
return self.vips[vip] ~= nil
end

local function canAdd(self)
local player = Player(self.guid)
if not player then
debugPrint("[Error - Vip::canAdd] null player (" .. self.guid .. ") when check if can add Vip.")
return 0
end

return #self.vips < player:getMaxVipEntries()
end

function Vip(guid)
if not Vips[guid] then
Vips[guid] = {
guid = guid,
clear = clear,
getList = getList,
add = add,
remove = remove,
has = has,
canAdd = canAdd,
vips = {}
}
end
return Vips[guid]
end
end
67 changes: 67 additions & 0 deletions data/scripts/creaturescripts/player/viplist.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
local function notifyAllPlayers(guid, status)
for _, player in ipairs(Game.getPlayers()) do
if player:getGuid() ~= guid then
player:notifyVipStatusChange(guid, status)
end
end
end

do
local event = CreatureEvent("OnlineVip")

function event.onLogin(player)
local playerGuid = player:getGuid()
notifyAllPlayers(playerGuid, VIPSTATUS_ONLINE)

local accountId = player:getAccountId()
local resultId = db.storeQuery("SELECT `player_id`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `name`, `description`, `icon`, `notify` FROM `account_viplist` WHERE `account_id` = " .. accountId)
ramon-bernardo marked this conversation as resolved.
Show resolved Hide resolved
if not resultId then
return true
end

local playerVip = Vip(playerGuid)
repeat
local vipGuid = result.getNumber(resultId, "player_id")
local vipName = result.getString(resultId, "name")
local description = result.getString(resultId, "description")
local icon = result.getNumber(resultId, "icon")
local notify = result.getNumber(resultId, "notify") ~= 0

-- add to player Vip cache
playerVip:add(vipGuid)

-- calculate the Vip status
local status
local vipPlayer = Player(vipGuid)
if vipPlayer and player:canSeeCreature(vipPlayer) then
status = VIPSTATUS_ONLINE
else
status = VIPSTATUS_OFFLINE
end

-- send to client
player:sendVip(vipGuid, vipName, description, icon, notify, status)
until not result.next(resultId)
result.free(resultId)

return true
end

event:register()
end

do
local event = CreatureEvent("OfflineVip")

function event.onLogout(player)
local playerGuid = player:getGuid()
notifyAllPlayers(playerGuid, VIPSTATUS_OFFLINE)

local playerVip = Vip(playerGuid)
playerVip:clear()
return true
end

event:register()
end

39 changes: 39 additions & 0 deletions data/scripts/network/viplist.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

do
-- Request add vip
local handler = PacketHandler(0xDC)

function handler.onReceive(player, msg)
local name = msg:getString()
player:addVip(name)
end

handler:register()
end

do
-- Request remove vip
local handler = PacketHandler(0xDD)

function handler.onReceive(player, msg)
local vipGuid = msg:getU32()
player:removeVip(vipGuid)
end

handler:register()
end

do
-- Request edit vip
local handler = PacketHandler(0xDE)

function handler.onReceive(player, msg)
local vipGuid = msg:getU32()
local description = msg:getString()
local icon = math.min(10, msg:getU32()) -- 10 is max icon in 9.63
local notify = msg:getByte() ~= 0
player:editVip(vipGuid, description, icon, notify)
end

handler:register()
end
2 changes: 0 additions & 2 deletions src/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,6 @@ bool ConfigManager::load()
integer[SERVER_SAVE_NOTIFY_DURATION] = getGlobalNumber(L, "serverSaveNotifyDuration", 5);
integer[YELL_MINIMUM_LEVEL] = getGlobalNumber(L, "yellMinimumLevel", 2);
integer[MINIMUM_LEVEL_TO_SEND_PRIVATE] = getGlobalNumber(L, "minimumLevelToSendPrivate", 1);
integer[VIP_FREE_LIMIT] = getGlobalNumber(L, "vipFreeLimit", 20);
integer[VIP_PREMIUM_LIMIT] = getGlobalNumber(L, "vipPremiumLimit", 100);
integer[DEPOT_FREE_LIMIT] = getGlobalNumber(L, "depotFreeLimit", 2000);
integer[DEPOT_PREMIUM_LIMIT] = getGlobalNumber(L, "depotPremiumLimit", 15000);
integer[QUEST_TRACKER_FREE_LIMIT] = getGlobalNumber(L, "questTrackerFreeLimit", 10);
Expand Down
Loading
Loading