Hi all,
One thing that has always pained me when I released the HNS mod was people using my maps before I released them (IE downloading them when they join the server then uploading them onto their own servers for use) so I developed a way to lock said map so it was only functioning on my server.
Now before I begin I would like to mention I am a huge supporter for open releases and free sharing. This method is generally for beta testing your map prior to release, so buggy maps aren't distributed - can also use this method to sell customized maps if your into that sort of thing.
BE SURE TO SAVE A SEPARATE COPY OF YOUR MAP FOR THIS TUTORIAL
Requirements
This method will require some tools and knowledge.- Eventscripts knowledge - basic
- Mapping knowledge - Intermediate
- Eventscripts plugin (installed on server, latest version)
The concept
The method used for locking the map is simply - ent_fire commands and AddOutput functions.
When you create a brush entity, that entity will most likely have a name and a series of inputs (example: func_door has the ability to be named and can be locked, opened, closed, killed etc).
The three main ways to lock a map with this technique is the following:- logic entities
- I/O replacement
- Locking entities
I will touch more on these later.
Where do I start?
When implementing this locking technique, it is important to build your map as you normally would - functioning. This technique is applied once the I/O is completed and functioning, so all solo beta testing should be done before attempting this.
Copy the below code into a new notepad file and save it as es_YOURMAPNAME.txt and place it in a folder called YOURMAPNAME. For example if my map was called ba_cool_prison, I would name the script es_ba_cool_prison and save it in a folder called ba_cool_prison.
Code:
block load
{
// Set the map name here (replace the 0)
es_xset map_name 0
es_xmsg #multi #greenMap Protection Script has been loaded!
es_xset locked_map_version 1.0
es_xmakepublic locked_map_version
es_xset map_is_loaded 0
}
event round_start
{
if (server_var(map_is_loaded) == 1) do
{
// random player variable we are storing
es_xset random_player 0
// Gets a random players userid and stores in our variable
getrandplayer random_player #all
}
}
event es_map_load
{
if (server_var(eventscripts_currentmap) == server_var(map_name)) do
{
es_xset map_is_loaded 1
}
}
On the first part of the code, under the heading block_load, find the line that says "es_xset map_name 0" and change the 0 to the name of your map.
I will now explain the different methods of locking:
Logic entities
These are a good way to make your map do crazy things if the user doesn't posses the script. A good way of implementing this is to create the following entities in your map:
Logic_timer - name it no_script_timer
point_servercommand - name it command
logic_auto - name it roundstart
In your logic_timer, add the following outputs:
Ontimer,command,command,say You are not supposed to be using this map!
Under class info, set the refire interval to 1
Under class info, set the start disabled to Yes
In your logic_auto, add the following outputs:
OnMapSpawn,no_script_timer,enable,10(delay)
This will spam that text continuously for the entire round if its not removed after 10 seconds.
You can also use the logic_auto to change the map to something else like cs_office by adding the following to Outputs:
OnMapSpawn,Command,Command,changelevel cs_office
What to add to the script:
Go into the script and add the following lines of code where I have:
Code:
event round_start
{
if (server_var(map_is_loaded) == 1) do
{
// random player variable we are storing
es_xset random_player 0
// Gets a random players userid and stores in our variable
getrandplayer random_player #all
// Removes the logic_timer
es_fire server_var(random_player) no_script_timer kill
// Removes the logic_auto
es_fire server_var(random_player) roundstart kill
}
}
This will kill both entities at round start every round, allowing full access to the map.
I/O Replacement
I/O replacement is by far the most effective form of locking a map as it can not be thwarted by the entspy tool.
The idea behind this technique is to remove parts of the output cycle and replace it with eventscripts commands. Unless the thief decompiles the map and knows exactly which I/O to fix, it is uncrackable.
An example of this is an important button in a map. Name the button important_button and take note of the outputs.
Example:
Button name: important_button
Current Outputs:
OnPressed,cell_doors,open,0,0
OnPressed,teleporter_t,enable,0,0
On the script, add the following so its similar to mine:
Code:
event round_start
{
if (server_var(map_is_loaded) == 1) do
{
// random player variable we are storing
es_xset random_player 0
// Gets a random players userid and stores in our variable
getrandplayer random_player #all
// Removes the logic_timer
es_fire server_var(random_player) no_script_timer kill
// Removes the logic_auto
es_fire server_var(random_player) roundstart kill
// Fix our I/O outputs so they work when the round starts
es_fire server_var(random_player) important_button addoutput "OnPressed,cell_doors,open"
es_fire server_var(random_player) important_button addoutput "OnPressed,teleporter_t,enable"
}
}
Be sure to change the functions of the outputs from cell_doors,open to what you noted in your current output.
Delete the output from your entity.
When players go to use your map on a lan server or another server that does not posses the script, the button will not function.
Locking Entities
This method is by far the easiest method, but the most crackable.
The idea behind it is to simply lock all entities that you want to lock, like doors, buttons etc. It can also disable teleporters, func_rotation entities etc.
To do this, simply get a list of entities that are lockable and tick the starts locked flag in hammer. Take note of all of the names of those entities (give them names if they don't have them) and add the following to the script:
Code:
event round_start
{
if (server_var(map_is_loaded) == 1) do
{
// random player variable we are storing
es_xset random_player 0
// Gets a random players userid and stores in our variable
getrandplayer random_player #all
// Removes the logic_timer
es_fire server_var(random_player) no_script_timer kill
// Removes the logic_auto
es_fire server_var(random_player) roundstart kill
// Fix our I/O outputs so they work when the round starts
es_fire server_var(random_player) important_button addoutput "OnPressed,cell_doors,open"
es_fire server_var(random_player) important_button addoutput "OnPressed,teleporter_t,enable"
// Unlock all the buttons/doors listed here
es_fire server_var(random_player) door1 unlock
es_fire server_var(random_player) cell_button unlock
es_fire server_var(random_player) other_custom_buttons unlock
// Enable all entities that are listed here
es_fire server_var(random_player) teleporter_t enable
es_fire server_var(random_player) func_rotation enable
}
}
Again, change the entity names in the script to match your own.
When the map spawns, all of the listed entities will be unlocked. Be strategic in the entities you choose to lock as it can be time and resource consuming to do them all, especially on larger maps.
Summary
If you followed this tutorial successfully, you will have learnt how to lock your maps for exclusive release. This is great in combination with other methods like map locking entities and Obfuscator's.
If you have any questions, I am happy to assist and I can create a script prefab for those who request it.
Enjoy!