Jump to content
Sign in to follow this  
V3ct0r

Promo code system

Recommended Posts

[Script] Promo code system

 

This script implements a simple promo code system. Players can use promo codes to get items. Promo codes are entered into the local chat channel through a slash, for example:

/agjtjSfsaAS34

 

The promo code can only be used once. A text file is used to store promo codes.

 

 

Requirements

 

The script requires GameServer.exe with the HandleChat() function support - local chat messages handler.

 

 

Installing the script

 

1) Create a file named "pkodev.promo.lua" in the folder "GameServer\resource\script\calculate\mods" with the following contents:

-- Print a log
print("Loading pkodev.promo.lua")

-- Check that HandleChat function exists
if (HandleChat == nil) then
	
	-- Write a log
	print("pkodev.promo.lua: Warning, the HandleChat() function is not exist!")
	
	-- Do not load the script
	return
	
end

-- Promocodes system
promo = promo or { }

-- Name of the file with promocodes
promo.file = "promocodes.dat"

-- List with promocodes
promo.list = {}

-- Save data to file
promo.save = function(path)
	
	-- Open the file
	local file, msg = io.open(path, "w")
	
	-- Check that file is open
	if (file == nil) then
		
		-- Write a log
		LG("pkodev.mod.promo", string.format("Can't save the list with promocodes to the file '%s': '%s'!", path, msg))
		return false
		
	end
	
	-- Write data
	for key, value in promo.list do
		
		-- Write a line
		local ret = file:write(string.format("{%s, %d, %d}\n", value.code, value.id, value.count))

		-- Check that line is written
		if (ret == false) then
		
			-- Write a log
			LG("pkodev.mod.promo", string.format("Can't write the data to the file '%s'!", path))
			return false
		
		end
	
	end
	
	-- Flush the data
	file:flush()
	
	-- Close the file
	file:close()
	
	-- Write a log
	LG("pkodev.mod.promo", string.format("The list with promocodes has been successfully saved to the file '%s'!", path))
	return true
	
end

-- Load data from file
promo.load = function(path)
	
	-- Remove old promocodes
	for k in pairs (promo.list) do
		promo.list[k] = nil
	end
	
	-- Open the file
	local file, msg = io.open(path, "r")
	
	-- Check that file is open
	if (file == nil) then
		
		-- Write a log
		LG("pkodev.mod.promo", string.format("Can't load the list with promocodes from the file '%s': '%s'!", path, msg))
		return false
		
	end

	-- Read file line by line
	for line in file:lines() do
			
		-- Extract data from the line
		local ret, _, code_, id_, count_ = string.find(line, "^{([A-Za-z0-9]+)%s*,%s*([0-9]+)%s*,%s*([0-9]+)}$")
		
		-- Check that string matches the pattern
		if (ret ~= nil) then
			
			-- Add data to the list
			table.insert(
				promo.list,
				{ 
					code  = code_,
					id    = id_,
					count = count_,
				}
			)
			
		end
		
	end
	
	-- Close the file
	file:close()
	
	-- Write a log
	LG("pkodev.mod.promo", string.format("%d promocodes have been succsessfully loaded from file '%s'!", table.getn(promo.list), path))
	return true

end

-- Handle chat function hook
promo.hadle_chat__original = HandleChat
HandleChat = function(role, msg)
	
	-- Check that message has the '/' symbol
	if ( string.sub(msg, 1, 1) == "/" ) then
	
		-- Get promocode
		local ret, _, code_ = string.find(msg, "^/([A-Za-z0-9]+)%s*$")
		
		-- Check that promocode is found
		if (ret ~= nil) then
			
			-- Search the promocode in the list
			for key, value in pairs(promo.list) do
				
				-- Compare promocodes
				if (value.code == code_) then
					
					-- Write a message
					BickerNotice(role, string.format("You entered the promocode '%s': %s x %d!",
						value.code, GetItemName(value.id), value.count) )
						
					
					-- Give an item
					GiveItem(role, 0, value.id, value.count, 0)
					
					-- Write a log
					LG("pkodev.mod.promo", string.format("Player '%s' entered a promocode '%s' and received '%s' x %d!",
						GetChaDefaultName(role), value.code, GetItemName(value.id), value.count) )
						
					-- Remove the promocode from the list
					promo.list[key] = nil
					
					-- Save the list to the file
					promo.save(promo.file)
					
					-- Synchronize the promocodes list
					local packet = GetPacket()
					WriteCmd(packet, 4015)
					WriteDword(packet, GetRoleID(role))
					WriteString(packet, string.format("promo.list[%d]=nil", key))
					SendPacket(role, packet)
					
					-- Do not call the original function HandleChat()
					return 0
					
				end
				
			end
			
		end
		
	end
	
	-- Call the original function HandleChat()
	return promo.hadle_chat__original(role, msg)
	
end

promo.load(promo.file)

2) Include it in the file "SkillEffect.lua" (\GameServer\resource\script\calculate) after "functions.lua" inclusion:

dofile(GetResPath("script\\calculate\\mods\\pkodev.promo.lua"))

3) In the root directory of the GameServer create a file named "promocodes.dat" and write the list of promocodes in the following format:

{<Promocode>, <Item ID>, <Item number>}

Example:

{agjtjSfsaAS34, 1849, 45}
{kgjKKKsnggklsaa, 885, 1}
{0004121aAf, 1848, 10}

 

 

Using the script

 

1) To use a promocode, player should enter it in the local chat:

/agjtjSfsaAS34

The player will get Cake x 45.

 

2) All logs regarding promo codes usage can be found in the file:

GameServer\LOG\log\pkodev.mod.promo.txt

 

 

What can be improved

 

1) As a reward, you can also give gold, buffs and other bonuses;

2) The list of promotional codes can be stored in the database, for example, using the LuaSQL library;

3) You can make promotional codes reusable, but one player can use the promotional code only once.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Bug fix 02/22/2022

 

On 2/18/2022 at 7:49 PM, V3ct0r said:

I just realized that my script has a critical bug. On all GameServer instances, a list of promotional codes is written to their memory. When a player uses a promotional code on one GameServer.exe, the others do not know about it. Thus, the player can use the procode several times. We need to come up with a way to synchronize the list of promotional codes between several GateServer.exe. Or allow the use of promotional codes on only one map (GameServer.exe instance).

 

The script has been updated.

  • Thanks 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...