Add files via upload

This commit is contained in:
Dinkledork
2023-02-15 15:03:35 -07:00
committed by GitHub
parent dd1599b445
commit 20cf067590
2 changed files with 808 additions and 0 deletions

750
CarbonCopy.lua Normal file
View File

@@ -0,0 +1,750 @@
--
-- Created by IntelliJ IDEA.
-- User: Silvia
-- Date: 18/02/2021
-- Time: 23:28
-- To change this template use File | Settings | File Templates.
-- Originally created by Honey for Azerothcore
-- requires ElunaLua module
------------------------------------------------------------------------------------------------
-- ADMIN GUIDE: - compile the core with ElunaLua module
-- - adjust config in this file
-- - add this script to ../lua_scripts/
-- - grant account related tickets in the `carboncopy` table
-- PLAYER USAGE: 1) create a new character with same class/race as the one to copy in the same account. Do NOT log it in
-- 2) log in with the source character
-- 3) .carboncopy newToonsName and wait one minute
------------------------------------------------------------------------------------------------
local Config = {};
local cc_maps = {};
local ticket_Cost = {};
-- Name of Eluna dB scheme
Config.customDbName = 'ac_eluna';
-- Min GM Level to use the .carboncopy command. Set to 0 for all players.
Config.minGMRankForCopy = 0;
-- Min GM Level to add tickets to an account.
Config.minGMRankForTickets = 2;
-- The amount of free tickets to grant when .carboncopy is executed for the first time on that account
Config.freeTickets = 1;
-- This text is added to the mail which the new character receives alongside their copied items
Config.mailText = ",\n \n here you are your gear. Have fun with the new twink!\n \n- Sincerely,\n the team of ChromieCraft!";
-- Maximum level to allow copying a character.
Config.maxLevel = 49;
-- Whether the ticket amount withdrawn for a copy is always 1 (set it to "single") or depends on the level (set this to "level")
Config.ticketCost = "level";
-- Here you can adjust the cost in tickets if Config.ticketCost is set to "level"
ticket_Cost[19] = 0
ticket_Cost[29] = 0
ticket_Cost[39] = 0
ticket_Cost[49] = 0
ticket_Cost[59] = 0
ticket_Cost[69] = 0
ticket_Cost[79] = 0
ticket_Cost[80] = 0
-- The maps below specify legal locations to use the .carboncopy command.
-- This is used to prevent dungeon specific gear to be copied e.g. the legendaries from the Kael'thas encounter.
-- Eastern kingdoms
table.insert(cc_maps, 0)
-- Kalimdor
table.insert(cc_maps, 1)
-- Outland
table.insert(cc_maps, 530)
-- Northrend
table.insert(cc_maps, 571)
------------------------------------------
-- NO ADJUSTMENTS REQUIRED BELOW THIS LINE
------------------------------------------
--Globals (see cleanup function for non-arrays)
cc_oldItemGuids = {}
cc_newItemGuids = {}
cc_scriptIsBusy = 0
-- If module runs for the first time, create the db specified in Config.dbName and add the "carboncopy" table to it.
CharDBQuery('CREATE DATABASE IF NOT EXISTS `'..Config.customDbName..'`;');
CharDBQuery('CREATE TABLE IF NOT EXISTS `'..Config.customDbName..'`.`carboncopy` (`account_id` INT(11) NOT NULL, `tickets` INT(11) DEFAULT 0, `allow_copy_from_id` INT(11) DEFAULT 0, PRIMARY KEY (`account_id`) );');
function cc_CopyCharacter(event, player, command, chatHandler)
local commandArray = cc_splitString(command)
if commandArray[2] ~= nil then
commandArray[2] = commandArray[2]:gsub("[';\\, ]", "")
if commandArray[3] ~= nil then
commandArray[3] = commandArray[3]:gsub("[';\\, ]", "")
end
end
if commandArray[1] ~= "carboncopy" and commandArray[1] ~= "addcctickets" and commandArray[1] ~= "CCACCOUNTTICKETS" then
return
end
if cc_scriptIsBusy ~= 0 then
chatHandler:SendSysMessage("The server is currently busy. Please try again in a few seconds.")
PrintInfo("CarbonCopy user request failed because the script has a scheduled task.")
return false
end
if commandArray[1] == "carboncopy" then
if player == nil then
chatHandler:SendSysMessage("This command can not be run from the console, but only from the character to copy.")
chatHandler:SendSysMessage("Expected syntax: .addcctickets $CharacterName $Amount")
return false
end
-- make sure the player is properly ranked
if player:GetGMRank() < Config.minGMRankForCopy then
chatHandler:SendSysMessage("You lack permisisions to execute this command.")
cc_resetVariables()
return false
end
-- provide syntax help
if commandArray[2] == "help" then
chatHandler:SendSysMessage("Syntax: .carboncopy $NewCharacterName")
cc_resetVariables()
return false
end
-- print the available tickets
local accountId = player:GetAccountId()
if commandArray[2] == nil then
local Data_SQL
Data_SQL = CharDBQuery('SELECT `tickets` FROM `'..Config.customDbName..'`.`carboncopy` WHERE `account_id` = '..accountId..' LIMIT 1;');
if Data_SQL ~= nil then
oldTickets = Data_SQL:GetUInt32(0)
else
oldTickets = Config.freeTickets
CharDBExecute('REPLACE INTO `'..Config.customDbName..'`.`carboncopy` VALUES ('..accountId..', '..Config.freeTickets..', 0) ;')
end
chatHandler:SendSysMessage("You currently have "..oldTickets.." tickets available for CarbonCopy.")
cc_resetVariables()
return false
end
-- check maxLevel
if player:GetLevel() > Config.maxLevel then
chatHandler:SendSysMessage("The character you want to copy from is too high level. Max level is "..Config.maxLevel..". Aborting.")
cc_resetVariables()
return false
end
cc_playerGUID = tostring(player:GetGUID())
cc_playerGUID = tonumber(cc_playerGUID)
local targetName = commandArray[2]:gsub("^%l", string.upper)
--check for target character to be on same account
local Data_SQL = CharDBQuery('SELECT `account` FROM `characters` WHERE `name` = "'..targetName..'" LIMIT 1;');
if Data_SQL == nil then
chatHandler:SendSysMessage("Name not found. Check spelling. Aborting.")
cc_resetVariables()
return false
end
local targetAccountId = Data_SQL:GetUInt32(0)
Data_SQL = nil
if targetAccountId ~= accountId then
chatHandler:SendSysMessage("The requested character is not on the same account. Aborting.")
cc_resetVariables()
return false
end
local Data_SQL = CharDBQuery('SELECT `guid` FROM `characters` WHERE `name` = "'..targetName..'" LIMIT 1;');
local newCharacter
if Data_SQL ~= nil then
newCharacter = Data_SQL:GetUInt32(0)
else
chatHandler:SendSysMessage("Name not found. Check spelling. Aborting.")
cc_resetVariables()
return false
end
Data_SQL = nil
--check for available tickets
local Data_SQL = CharDBQuery('SELECT `tickets` FROM `'..Config.customDbName..'`.`carboncopy` WHERE `account_id` = '..accountId..';');
local availableTickets
local requiredTickets
if Data_SQL ~= nil then
availableTickets = Data_SQL:GetUInt32(0)
Data_SQL = nil
else
CharDBExecute('REPLACE INTO `'..Config.customDbName..'`.`carboncopy` VALUES ('..accountId..', '..Config.freeTickets..', 0) ;')
availableTickets = Config.freeTickets
end
if Config.ticketCost == "single" then
if availableTickets ~= nil and availableTickets <= 0 then
chatHandler:SendSysMessage("You do not have enough Carbon Copy tickets to execute this command. Aborting.")
cc_resetVariables()
return false
end
requiredTickets = 1
elseif Config.ticketCost == "level" then
local Data_SQL = CharDBQuery('SELECT `level` FROM `characters` WHERE `guid` = '..cc_playerGUID..' LIMIT 1;');
local n = Data_SQL:GetUInt8(0) - 1
repeat
n = n + 1
until ticket_Cost[n] ~= nil
requiredTickets = ticket_Cost[n]
if availableTickets ~= nil and availableTickets <= 0 then
chatHandler:SendSysMessage("You do not have enough Carbon Copy tickets to execute this command. Aborting.")
cc_resetVariables()
return false
end
if availableTickets < requiredTickets then
chatHandler:SendSysMessage("You do not have enough Carbon Copy tickets to execute this command. Aborting.")
cc_resetVariables()
return false
end
Data_SQL = nil
else
PrintError("Unhandled exception in CarbonCopy. Config.ticketCost is neither set to \"single\" nor \"level\".")
end
--check for target character to be same class/race
local Data_SQL = CharDBQuery('SELECT `race`, `class` FROM `characters` WHERE `guid` = '..cc_playerGUID..' LIMIT 1;');
local sourceRace = Data_SQL:GetUInt8(0)
local sourceClass = Data_SQL:GetUInt8(1)
Data_SQL = nil
local Data_SQL = CharDBQuery('SELECT `race`, `class` FROM `characters` WHERE `guid` = '..newCharacter..' LIMIT 1;');
local targetRace = Data_SQL:GetUInt8(0)
local targetClass = Data_SQL:GetUInt8(1)
Data_SQL = nil
if sourceRace ~= targetRace then
chatHandler:SendSysMessage("The requested character is not the same race as this character. Aborting.")
cc_resetVariables()
return false
end
if sourceClass ~= targetClass then
chatHandler:SendSysMessage("The requested character is not the same class as this character. Aborting.")
cc_resetVariables()
return false
end
-- check if target character wasn't logged in
local cc_cinematic
local Data_SQL = CharDBQuery('SELECT cinematic FROM characters WHERE guid = '..newCharacter..';');
if Data_SQL ~= nil then
cc_cinematic = Data_SQL:GetUInt16(0)
if cc_cinematic == 1 then
chatHandler:SendSysMessage("The requested character has been logged in already. Aborting.")
cc_cinematic = nil
cc_resetVariables()
return false
end
else
PrintError("Unhandled exception in CarbonCopy. Could not read characters.cinematic from cc_playerGUID "..newCharacter..".")
end
-- check if target character is logged in currently in case cinematic wasnt already written to db
local cc_online
local Data_SQL = CharDBQuery('SELECT online FROM characters WHERE guid = '..newCharacter..';');
if Data_SQL ~= nil then
cc_online = Data_SQL:GetUInt16(0)
if cc_online == 1 then
chatHandler:SendSysMessage("The requested character has been logged in already. Aborting.")
cc_online = nil
cc_resetVariables()
return false
end
else
PrintError("Unhandled exception in CarbonCopy. Could not read characters.online from cc_playerGUID "..newCharacter..".")
end
-- check source characters location
local cc_mapId
cc_mapId = player:GetMapId()
if not cc_has_value(cc_maps, cc_mapId) then
chatHandler:SendSysMessage("You are not in an allowed map. Try again outside/not in a dungeon.")
cc_resetVariables()
return false
end
-------------- COPY SCRIPT STARTS HERE ---------------------
--set Global variable to prevent simultaneous action and lock the target for 15 seconds
Ban(1, targetName, 15, "CarbonCopy", "CarbonCopy" )
cc_scriptIsBusy = 1
cc_newCharacter = newCharacter
-- save the source character to db to prevent recent changes from being not applied
player:SaveToDB()
--fetch all required variables before 1st yield
cc_playerString = player:GetClassAsString(0)
PrintInfo("1) The player with GUID "..cc_playerGUID.." has succesfully initiated the .carboncopy command. Target character: "..cc_newCharacter);
chatHandler:SendSysMessage("Copy started. You have been charged "..requiredTickets.." ticket(s) for this action. There are "..availableTickets - requiredTickets.." ticket()s left.")
chatHandler:SendSysMessage("STAY logged in for one minute!")
chatHandler:SendSysMessage("RIMANENTE connessi per un minuto!")
chatHandler:SendSysMessage("MANTENTE conectado por un minuto!")
chatHandler:SendSysMessage("BLEIB eingeloggt für eine Minute!")
cc_eventId = CreateLuaEvent(cc_resumeSubRoutine, 1000, 10)
cc_subRoutine = coroutine.create(function ()
-- deduct tickets
if Config.ticketCost == "single" then
local Data_SQL = CharDBQuery('UPDATE `'..Config.customDbName..'`.`carboncopy` SET tickets = tickets -1 WHERE `account_id` = '..accountId..';');
Data_SQL = nil
elseif Config.ticketCost == "level" then
local Data_SQL = CharDBQuery('UPDATE `'..Config.customDbName..'`.`carboncopy` SET tickets = tickets -'..requiredTickets..' WHERE `account_id` = '..accountId..';');
Data_SQL = nil
end
-- delete TempTables
cc_deleteTempTables(cc_playerGUID)
-- Copy characters table
local QueryString
QueryString = 'UPDATE `characters` AS t1 '
QueryString = QueryString..'INNER JOIN `characters` AS t2 ON t2.guid = '..cc_playerGUID..' '
QueryString = QueryString..'SET t1.level = t2.level, t1.xp = t2.xp, t1.taximask = t2.taximask, t1.totaltime = t2.totaltime, '
QueryString = QueryString..'t1.leveltime = t2.leveltime, t1.stable_slots = t2.stable_slots, t1.health = t2.health, '
QueryString = QueryString..'t1.power1 = t2.power1, t1.power2 = t2.power2, t1.power3 = t2.power3, t1.power4 = t2.power4, '
QueryString = QueryString..'t1.power5 = t2.power5, t1.power6 = t2.power6, t1.power7 = t2.power7, t1.talentGroupsCount = t2.talentGroupsCount, '
QueryString = QueryString..'t1.exploredZones = t2.exploredZones WHERE t1.guid = '..cc_newCharacter..';'
local Data_SQL = CharDBQuery(QueryString);
QueryString = nil
Data_SQL = nil
local Data_SQL = CharDBQuery('UPDATE characters SET cinematic = 1 WHERE guid = '..cc_newCharacter..';');
coroutine.yield()
-- Copy character_homebind
local Data_SQL = CharDBQuery('DELETE FROM character_homebind WHERE guid = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('INSERT INTO character_homebind VALUES ('..cc_newCharacter..' ,0,0,0,0,0);')
QueryString = 'UPDATE character_homebind AS t1 INNER JOIN character_homebind AS t2 ON t2.guid = '..cc_playerGUID..' '
QueryString = QueryString..'SET t1.mapId = t2.mapId, t1.zoneId = t2.zoneId, t1.posX = t2.posX, t1.posY = t2.posY, t1.posZ = t2.posZ '
QueryString = QueryString..'WHERE t1.guid = '..cc_newCharacter..';'
local Data_SQL = CharDBQuery(QueryString);
QueryString = nil
Data_SQL = nil
-- Copy character_pet and totems
if cc_playerString == "Hunter" then
local Data_SQL = CharDBQuery('SELECT id FROM character_pet WHERE owner = '..cc_playerGUID..' LIMIT 1;');
if Data_SQL ~= nil then
cc_playerPetId = Data_SQL:GetUInt32(0)
Data_SQL = nil
local Data_SQL = CharDBQuery('SELECT MAX(id) FROM character_pet;');
local cc_targetPetId = Data_SQL:GetUInt32(0) + 1
Data_SQL = nil
local Data_SQL = CharDBQuery('DELETE FROM character_pet WHERE owner = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempPet'..cc_playerGUID..' LIKE character_pet;')
local Data_SQL = CharDBQuery('INSERT INTO tempPet'..cc_playerGUID..' SELECT * FROM character_pet WHERE id = '..cc_playerPetId..';')
local Data_SQL = CharDBQuery('UPDATE tempPet'..cc_playerGUID..' SET id = '..cc_targetPetId..', slot = 0, owner = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('INSERT INTO character_pet SELECT * FROM tempPet'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempPet'..cc_playerGUID..';')
QueryString = nil
Data_SQL = nil
local Data_SQL = CharDBQuery('DELETE FROM pet_spell WHERE guid = '..cc_targetPetId..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempPet_spell'..cc_playerGUID..' LIKE pet_spell;')
local Data_SQL = CharDBQuery('INSERT INTO tempPet_spell'..cc_playerGUID..' SELECT * FROM pet_spell WHERE guid = '..cc_playerPetId..';')
local Data_SQL = CharDBQuery('UPDATE tempPet_spell'..cc_playerGUID..' SET guid = '..cc_targetPetId..' WHERE guid = '..cc_playerPetId..';')
local Data_SQL = CharDBQuery('INSERT INTO pet_spell SELECT * FROM tempPet_spell'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempPet_spell'..cc_playerGUID..';')
QueryString = nil
Data_SQL = nil
end
elseif cc_playerString == "Shaman" then
local totemItem = {}
totemItem[1] = 38
totemItem[2] = 38
totemItem[3] = 38
totemItem[4] = 38
local totemsDone = 0
local Data_SQL
Data_SQL = CharDBQuery('SELECT itemEntry FROM item_instance WHERE owner_guid = '..cc_playerGUID..' AND itemEntry = 5178 LIMIT 1;')
if Data_SQL ~= nil then
if Data_SQL:GetUInt16(0) == 5178 then
totemItem[4] = 5178
end
end
Data_SQL = nil
local Data_SQL
Data_SQL = CharDBQuery('SELECT itemEntry FROM item_instance WHERE owner_guid = '..cc_playerGUID..' AND itemEntry = 5177 LIMIT 1;')
if Data_SQL ~= nil then
if Data_SQL:GetUInt16(0) == 5177 then
totemItem[3] = 5177
end
end
Data_SQL = nil
local Data_SQL
Data_SQL = CharDBQuery('SELECT itemEntry FROM item_instance WHERE owner_guid = '..cc_playerGUID..' AND itemEntry = 5176 LIMIT 1;')
if Data_SQL ~= nil then
if Data_SQL:GetUInt16(0) == 5176 then
totemItem[2] = 5176
end
end
Data_SQL = nil
local Data_SQL
Data_SQL = CharDBQuery('SELECT itemEntry FROM item_instance WHERE owner_guid = '..cc_playerGUID..' AND itemEntry = 5175 LIMIT 1;')
if Data_SQL ~= nil then
if Data_SQL:GetUInt16(0) == 5175 then
totemItem[1] = 5175
end
end
Data_SQL = nil
SendMail("Copied items", "Hello "..targetName..Config.mailText, cc_newCharacter, 0, 61, 0, 0, 0, totemItem[1], 1, totemItem[2], 1, totemItem[3], 1, totemItem[4], 1)
Data_SQL = nil
totemsDone = nil
end
coroutine.yield()
--Copy quests
local Data_SQL = CharDBQuery('DELETE FROM character_queststatus_rewarded WHERE guid = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempQuest'..cc_playerGUID..' LIKE character_queststatus_rewarded;')
local Data_SQL = CharDBQuery('INSERT INTO tempQuest'..cc_playerGUID..' SELECT * FROM character_queststatus_rewarded WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('UPDATE tempQuest'..cc_playerGUID..' SET guid = '..cc_newCharacter..' WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('INSERT INTO character_queststatus_rewarded SELECT * FROM tempQuest'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempQuest'..cc_playerGUID..';')
Data_SQL = nil
coroutine.yield()
--Copy reputation
local Data_SQL = CharDBQuery('DELETE FROM character_reputation WHERE guid = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempReputation'..cc_playerGUID..' LIKE character_reputation;')
local Data_SQL = CharDBQuery('INSERT INTO tempReputation'..cc_playerGUID..' SELECT * FROM character_reputation WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('UPDATE tempReputation'..cc_playerGUID..' SET guid = '..cc_newCharacter..' WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('INSERT INTO character_reputation SELECT * FROM tempReputation'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempReputation'..cc_playerGUID..';')
Data_SQL = nil
coroutine.yield()
--Copy skills
local Data_SQL = CharDBQuery('DELETE FROM character_skills WHERE guid = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempSkills'..cc_playerGUID..' LIKE character_skills;')
local Data_SQL = CharDBQuery('INSERT INTO tempSkills'..cc_playerGUID..' SELECT * FROM character_skills WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('UPDATE tempSkills'..cc_playerGUID..' SET guid = '..cc_newCharacter..' WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('INSERT INTO character_skills SELECT * FROM tempSkills'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempSkills'..cc_playerGUID..';')
Data_SQL = nil
coroutine.yield()
--Copy spells
local Data_SQL = CharDBQuery('DELETE FROM character_spell WHERE guid = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempSpell'..cc_playerGUID..' LIKE character_spell;')
local Data_SQL = CharDBQuery('INSERT INTO tempSpell'..cc_playerGUID..' SELECT * FROM character_spell WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('UPDATE tempSpell'..cc_playerGUID..' SET guid = '..cc_newCharacter..' WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('INSERT INTO character_spell SELECT * FROM tempSpell'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempSpell'..cc_playerGUID..';')
Data_SQL = nil
coroutine.yield()
--Copy talents
local Data_SQL = CharDBQuery('DELETE FROM character_talent WHERE guid = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempTalent'..cc_playerGUID..' LIKE character_talent;')
local Data_SQL = CharDBQuery('INSERT INTO tempTalent'..cc_playerGUID..' SELECT * FROM character_talent WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('UPDATE tempTalent'..cc_playerGUID..' SET guid = '..cc_newCharacter..' WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('INSERT INTO character_talent SELECT * FROM tempTalent'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempTalent'..cc_playerGUID..';')
Data_SQL = nil
coroutine.yield()
--Copy glyphs
local Data_SQL = CharDBQuery('DELETE FROM character_glyphs WHERE guid = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempGlyphs'..cc_playerGUID..' LIKE character_glyphs;')
local Data_SQL = CharDBQuery('INSERT INTO tempGlyphs'..cc_playerGUID..' SELECT * FROM character_glyphs WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('UPDATE tempGlyphs'..cc_playerGUID..' SET guid = '..cc_newCharacter..' WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('INSERT INTO character_glyphs SELECT * FROM tempGlyphs'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempGlyphs'..cc_playerGUID..';')
Data_SQL = nil
coroutine.yield()
--Copy actions
local Data_SQL = CharDBQuery('DELETE FROM character_action WHERE guid = '..cc_newCharacter..';')
local Data_SQL = CharDBQuery('CREATE TEMPORARY TABLE tempAction'..cc_playerGUID..' LIKE character_action;')
local Data_SQL = CharDBQuery('INSERT INTO tempAction'..cc_playerGUID..' SELECT * FROM character_action WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('UPDATE tempAction'..cc_playerGUID..' SET guid = '..cc_newCharacter..' WHERE guid = '..cc_playerGUID..';')
local Data_SQL = CharDBQuery('INSERT INTO character_action SELECT * FROM tempAction'..cc_playerGUID..';')
local Data_SQL = CharDBQuery('DROP TABLE IF EXISTS tempAction'..cc_playerGUID..';')
Data_SQL = nil
coroutine.yield()
--Copy items
local homeStone
local Data_SQL = CharDBQuery('DELETE FROM item_instance WHERE owner_guid = '..cc_newCharacter..' AND itemEntry != 6948;')
local Data_SQL = CharDBQuery('SELECT guid FROM item_instance WHERE owner_guid = '..cc_newCharacter..' AND itemEntry = 6948 LIMIT 1;')
homeStone = Data_SQL:GetUInt32(0)
local Data_SQL = CharDBQuery('DELETE FROM character_inventory WHERE guid = '..cc_newCharacter..' AND item != '..homeStone..';')
Data_SQL = nil
local Data_SQL = CharDBQuery('SELECT item FROM character_inventory WHERE guid = '..cc_playerGUID..' AND bag = 0 AND slot <= 18 LIMIT 18;')
local ItemCounter = 1
local item_id = {}
local item_amount = {}
local i
if Data_SQL ~= nil then
repeat
cc_oldItemGuids[ItemCounter] = Data_SQL:GetUInt32(0)
local Data_SQL2 = CharDBQuery('SELECT itemEntry FROM item_instance WHERE guid = '..cc_oldItemGuids[ItemCounter]..' LIMIT 1;')
item_id[ItemCounter] = Data_SQL2:GetUInt16(0)
ItemCounter = ItemCounter + 1
until not Data_SQL:NextRow()
-- set amounts to 1 or nil
for i = 1,18,1 do
if item_id[i] ~= nil then
item_amount[i] = 1
else
item_amount[i] = 1
item_id[i] = 38
end
end
cc_newItemGuids[1], cc_newItemGuids[2], cc_newItemGuids[3], cc_newItemGuids[4], cc_newItemGuids[5], cc_newItemGuids[6], cc_newItemGuids[7], cc_newItemGuids[8], cc_newItemGuids[9], cc_newItemGuids[10], cc_newItemGuids[11], cc_newItemGuids[12] = SendMail("Copied items", "Hello "..targetName..Config.mailText, cc_newCharacter, 0, 61, 0, 0, 0, item_id[1], 1, item_id[2], 1, item_id[3], 1, item_id[4], 1, item_id[5], 1, item_id[6], 1, item_id[7], 1, item_id[8], 1, item_id[9], 1, item_id[10], 1, item_id[11], 1, item_id[12], 1)
if cc_oldItemGuids[13] ~= nil then
cc_newItemGuids[13], cc_newItemGuids[14], cc_newItemGuids[15], cc_newItemGuids[16], cc_newItemGuids[17], cc_newItemGuids[18] = SendMail("Copied items", "Hello "..targetName..Config.mailText, cc_newCharacter, 0, 61, 0, 0, 0, item_id[13], 1, item_id[14], 1, item_id[15], 1, item_id[16], 1, item_id[17], 1, item_id[18], 1)
end
end
CreateLuaEvent(cc_fixItems, 3000) -- do it after 3 seconds
cc_deleteTempTables(cc_playerGUID)
cc_resetVariables()
return false
end)
elseif commandArray[1] == "addcctickets" then
-- make sure the player is properly ranked
local accountId
local oldTickets
local Data_SQL
if player ~= nil then
if player:GetGMRank() < Config.minGMRankForTickets then
cc_resetVariables()
return false
end
if commandArray[2] == "help" then
chatHandler:SendSysMessage("Syntax: .addcctickets $CharacterName $Amount")
cc_resetVariables()
return false
end
if commandArray[2] == nil or commandArray[3] == nil then
chatHandler:SendSysMessage("Expected syntax: .addcctickets $CharacterName $Amount")
cc_resetVariables()
return false
end
if tonumber(commandArray[3]) > 1000 or tonumber(commandArray[3]) < 0 then
chatHandler:SendSysMessage("Too large or negative amount chosen for .addcctickets: "..commandArray[3]..". Max allowed is +1000.")
cc_resetVariables()
return false
end
Data_SQL = CharDBQuery("SELECT `account` FROM `characters` WHERE `name` = '"..tostring(commandArray[2]).."' LIMIT 1;");
if Data_SQL ~= nil then
accountId = Data_SQL:GetUInt32(0)
else
chatHandler:SendSysMessage("Player name not found. Expected syntax: .addcctickets [CharacterName] [Amount]")
cc_resetVariables()
return false
end
Data_SQL = nil
local Data_SQL
Data_SQL = CharDBQuery('SELECT `tickets` FROM `'..Config.customDbName..'`.`carboncopy` WHERE `account_id` = '..accountId..' LIMIT 1;');
if Data_SQL ~= nil then
oldTickets = Data_SQL:GetUInt32(0)
else
oldTickets = 0
end
Data_SQL = nil
if oldTickets >= 1000 or oldTickets < 0 then
chatHandler:SendSysMessage("Too large total amount tickets: "..commandArray[3]..". Max allowed total is +1000. Current value: "..oldTickets)
cc_resetVariables()
return false
end
-- the `allow_copy_from_id` column is hardcoded to 0 for now. Only copies to the same account are possible.
local Data_SQL
Data_SQL = CharDBQuery('DELETE FROM `'..Config.customDbName..'`.`carboncopy` WHERE `account_id` = '..accountId..';');
Data_SQL = CharDBQuery('INSERT INTO `'..Config.customDbName..'`.`carboncopy` VALUES ('..accountId..', '..commandArray[3] + oldTickets..', 0);');
Data_SQL = nil
chatHandler:SendSysMessage("GM "..player:GetName().. " has sucessfully used the .addcctickets command, adding "..commandArray[3].." tickets to the account "..accountId.." which belongs to player "..commandArray[2]..".")
cc_resetVariables()
return false
else
--player is nil, must be the console. no need to check gm rank and print to console only. not chat
if commandArray[2] == "help" then
chatHandler:SendSysMessage("Syntax: .addcctickets $CharacterName $Amount")
cc_resetVariables()
return false
end
if commandArray[2] == nil or commandArray[3] == nil then
chatHandler:SendSysMessage("Expected syntax: .addcctickets $CharacterName $Amount")
cc_resetVariables()
return false
end
if tonumber(commandArray[3]) > 1000 or tonumber(commandArray[3]) < 0 then
chatHandler:SendSysMessage("Too large or negative amount chosen for .addcctickets: "..commandArray[3]..". Max allowed is +1000.")
cc_resetVariables()
return false
end
Data_SQL = CharDBQuery("SELECT `account` FROM `characters` WHERE `name` = '"..tostring(commandArray[2]).."' LIMIT 1;");
if Data_SQL ~= nil then
accountId = Data_SQL:GetUInt32(0)
else
chatHandler:SendSysMessage("Player name not found. Expected syntax: .addcctickets [CharacterName] [Amount]")
cc_resetVariables()
return false
end
Data_SQL = nil
local Data_SQL
Data_SQL = CharDBQuery('SELECT `tickets` FROM `'..Config.customDbName..'`.`carboncopy` WHERE `account_id` = '..accountId..' LIMIT 1;');
if Data_SQL ~= nil then
oldTickets = Data_SQL:GetUInt32(0)
else
oldTickets = 0
end
Data_SQL = nil
if oldTickets >= 1000 or oldTickets < 0 then
chatHandler:SendSysMessage("Too large total amount tickets: "..commandArray[3]..". Max allowed total is +1000. Current value: "..oldTickets)
cc_resetVariables()
return false
end
-- the `allow_copy_from_id` column is hardcoded to 0 for now. Only copies to the same account are possible.
local Data_SQL
Data_SQL = CharDBQuery('DELETE FROM `'..Config.customDbName..'`.`carboncopy` WHERE `account_id` = '..accountId..';');
Data_SQL = CharDBQuery('INSERT INTO `'..Config.customDbName..'`.`carboncopy` VALUES ('..accountId..', '..commandArray[3] + oldTickets..', 0);');
Data_SQL = nil
chatHandler:SendSysMessage("The console has sucessfully used the .addcctickets command, adding "..commandArray[3].." tickets to the account "..accountId.." which belongs to player "..commandArray[2]..".")
cc_resetVariables()
return false
end
-- command for SOAP interface to send to worldserver console, granting tickets. Syntax: CCACCOUNTTICKETS $accountName $amount
elseif commandArray[1] == "CCACCOUNTTICKETS" and commandArray[2] ~= nil and commandArray[3] ~= nil and player == nil then
local Data_SQL
Data_SQL = AuthDBQuery('SELECT `id` FROM `account` WHERE `username` = "'..commandArray[2]..'";')
if Data_SQL == nil then
PrintError("CCACCOUNTTICKETS to "..commandArray[2].." has failed.")
cc_resetVariables()
return false
else
accountId = Data_SQL:GetUInt32(0)
end
if tonumber(commandArray[3]) > 1000 or tonumber(commandArray[3]) < 0 then
chatHandler:SendSysMessage("Too large or negative amount chosen for .CCACCOUNTTICKETS: "..commandArray[3]..". Max allowed is +1000.")
cc_resetVariables()
return false
end
Data_SQL = CharDBQuery('SELECT `tickets` FROM `'..Config.customDbName..'`.`carboncopy` WHERE `account_id` = '..accountId..' LIMIT 1;');
if Data_SQL ~= nil then
oldTickets = Data_SQL:GetUInt32(0)
else
oldTickets = 0
end
if oldTickets >= 1000 or oldTickets < 0 then
chatHandler:SendSysMessage("Too large total amount of tickets: "..commandArray[3]..". Max allowed total is +1000. Current value: "..oldTickets)
cc_resetVariables()
return false
end
CharDBExecute('REPLACE INTO `'..Config.customDbName..'`.`carboncopy` VALUES ('..accountId..', '..commandArray[3] + oldTickets..', 0) ;')
cc_resetVariables()
return false
elseif player ~= nil then
chatHandler:SendSysMessage("'CCACCOUNTTICKETS $accountName $amount' only works against SOAP / the console.")
return false
else
chatHandler:SendSysMessage("Expected Syntax: CCACCOUNTTICKETS $accountName $amount")
return false
end
end
function cc_fixItems()
local n
local Data_SQL
for n,_ in ipairs(cc_oldItemGuids) do
QueryString = 'UPDATE `item_instance` AS t1 '
QueryString = QueryString..'INNER JOIN `item_instance` AS t2 ON t2.guid = '..cc_oldItemGuids[n]..' '
QueryString = QueryString..'SET t1.owner_guid = '..cc_newCharacter..', t1.creatorGuid = t2.creatorGuid, '
QueryString = QueryString..'t1.duration = t2.duration, t1.charges = t2.charges, t1.flags = 1, '
QueryString = QueryString..'t1.enchantments = t2.enchantments, t1.randomPropertyId = t2.randomPropertyId '
QueryString = QueryString..'WHERE t1.guid = '..cc_newItemGuids[n]..';'
Data_SQL = CharDBQuery(QueryString);
end
GetPlayerByGUID(cc_playerGUID):SendBroadcastMessage("Character copy done. You can log out now.")
PrintInfo("2) Item enchants/gems copied for new character with GUID "..cc_newCharacter);
cc_newCharacter = 0
cc_oldItemGuids = {}
cc_newItemGuids = {}
cc_scriptIsBusy = 0
cc_playerGUID = nil
end
function cc_resetVariables()
Data_SQL = nil
Data_SQL2 = nil
ItemCounter = nil
targetName = nil
QueryString = nil
cc_playerPetId = nil
cc_targetPetId = nil
item_id = nil
homeStone = nil
cc_playerString = nil
cc_cinematic = nil
commandArray = nil
availableTickets = nil
newItemGuid = nil
end
function cc_deleteTempTables(cc_GUID)
CharDBQuery('DROP TABLE IF EXISTS tempQuest'..cc_GUID..';')
CharDBQuery('DROP TABLE IF EXISTS tempPet'..cc_GUID..';')
CharDBQuery('DROP TABLE IF EXISTS tempPet_spell'..cc_GUID..';')
CharDBQuery('DROP TABLE IF EXISTS tempReputation'..cc_GUID..';')
CharDBQuery('DROP TABLE IF EXISTS tempSkills'..cc_GUID..';')
CharDBQuery('DROP TABLE IF EXISTS tempSpell'..cc_GUID..';')
CharDBQuery('DROP TABLE IF EXISTS tempTalent'..cc_GUID..';')
CharDBQuery('DROP TABLE IF EXISTS tempGlyphs'..cc_GUID..';')
CharDBQuery('DROP TABLE IF EXISTS tempAction'..cc_GUID..';')
end
function cc_splitString(inputstr, seperator)
if seperator == nil then
seperator = "%s"
end
local t={}
for str in string.gmatch(inputstr, "([^"..seperator.."]+)") do
table.insert(t, str)
end
return t
end
function cc_has_value (tab, val)
for index, value in ipairs(tab) do
if value == val then
return true
end
end
return false
end
function cc_resumeSubRoutine(eventId, delay, repeats)
coroutine.resume(cc_subRoutine)
end
local PLAYER_EVENT_ON_COMMAND = 42
-- function to be called when the command hook fires
RegisterPlayerEvent(PLAYER_EVENT_ON_COMMAND, cc_CopyCharacter)