- Joined
- Nov 30, 2007
- Messages
- 1,202
The purpose of this library is to make the creation of commands faster and easier to manage by providing additional API geared towards that end. Among other things you can register commands, disable them for certain players, or all players, and define new player string identification. Read the manual for more examples and detail of what it does.
Example 1
Using the same trigger as before. We will create the same command but this time remove it once it has fired once.
You can also use the destroy method directly:
Example 2
What if I have two triggers registrated to the same command but only want to remove one? Worry not, you simply have to remeber the index of the trigger you want removed.
Since SpamHello was the last trigger registrated it will be indexed at position 1, and in this example "Hello Spam!" will only run once, where as "Hello, World!" runs always.
First a brief overview of the enable/disable API.
Example 1
Now lets take the above information and create a cooldown that limits how often a player can use the "-hello" command.
First a brief overview of the API.
Example 1
Iterating over all the words entered by the player.
Example 2
Creating a substring based on a combination of words using wordStart and wordEnd
Per default the library recognizes player numbers such as "1" for player red and player names. If you don't wish to permit player names as identifiers you can go to the global configurable block and set the variable ACK_PLAYER_NAME to false. You can also create your own string identifiers for players or remove the default player numbers, using the following API:
Example 1
Now let's create a command for kicking players that utilizes StrToPlayer to find out which player should be dropped.
Example 1
In this example we will create a cheat that is the same as the CreateUnit native. We will be using an external library for string to ascii conversion to get the unit type. The rest of the functions used exists inside the library.
[Snippet] Ascii
Example 2
In this example we'll be creating a -give command for sending players gold or wood.
Example 1
In this example we'll be creating a "-commands" command to get all available commands for the triggering player. But you could just as well use this to put it in a quest log or anything else really.
Note that the Init trigger is just an example to illustrate that if Player Red will not see the "-hello" command.
Finally, in this example you'll learn how to use the provided real variable events to process all entered chat messages and detect commands that were blocked from execution. This can be used for creating a chat system or displaying error messages for blocked commands.
Step by step:
1) Change the configurable: Set FILTER_PREFIX = ""
2) Scroll down in the library code until you find the static method "onChatEvent" inside the Command struct. Then change the variable (chat_event) inside the textmacros to your global variable.
3) Implement it in your chat trigger. It should look something like this:
That's it for this guide. Good job for reading it all!
JASS:
library CommandUtils uses Table
/*
===============================================================================================
Command Utilities version 1.3.
Latest version containing API and Manual can be found here:
hiveworkshop.com/threads/command-utilities.307554/
===============================================================================================
This libary provides a struct for each player, which stores information generated each time a
player enters a chat command. It's purpose is to make the creation of commands faster and easier
to manage by providing a few additional API functions geared towards that end.
Credits:
- Made by Pinzu
Requirements
- Table by Bribe
hiveworkshop.com/threads/snippet-new-table.188084/
Configuration
- Simply copy Bribe's Table and this library into your map
- Modify the configurables to your preference in the global block. You can add multiple command
prefixes if you scroll down to the onInit method inside Command struct.
===============================================================================================
*/
globals
private constant string FILTER_PREFIX = ""
private constant integer MAX_WORDS = 300
private constant boolean ACK_PLAYER_NAME = true
public real chat_event
public constant real RESET_CHAT_EVENT = 0
public constant real ON_CHAT_EVENT = 1
public constant real ON_CMD_BLOCKED = 2
private Table playerchat
private Table playerIds
endglobals
function GetPlayerChat takes player p returns PChat
return playerchat[GetPlayerId(p)]
endfunction
function GetLastUpdatedChat takes nothing returns PChat
return PChat.last
endfunction
function GetLastCommand takes nothing returns Command
return Command.last
endfunction
private function isDigit takes string c returns boolean
return c == "0" or c == "1" or c == "2" or c == "3" or c == "4" or c == "5" or /*
*/ c == "6" or c == "7" or c == "8" or c == "9"
endfunction
function StrIsReal takes string s returns boolean
local integer i = 0
local integer dots = 0
local string char
loop
exitwhen i == StringLength(s)
set char = SubString(s, i, i + 1)
if char == "." then
set dots = dots + 1
if dots > 1 then
return false
endif
elseif not isDigit(char) then
return false
endif
set i = i + 1
endloop
return true
endfunction
function StrIsInt takes string s returns boolean
local integer i = 0
local string char
local integer len = StringLength(s)
if len == 0 then
return false
endif
loop
exitwhen i == len
set char = SubString(s, i, i + 1)
if not isDigit(char) and not (i == 0 and char == "-") then
return false
endif
set i = i + 1
endloop
return true
endfunction
function StrIsBoolean takes string s returns boolean
set s = StringCase(s, false)
return s == "true" or s == "false"
endfunction
function S2B takes string s returns boolean
set s = StringCase(s, false)
if s == "true" then
return true
endif
return false
endfunction
function StrContainsDigit takes string s returns boolean
local integer length = StringLength(s)
local integer i = 0
local string c
set i = 0
loop
exitwhen i == length
set c = SubString(s, i, i + 1)
if isDigit(c) then
return true
endif
set i = i + 1
endloop
return false
endfunction
function StrToPlayer takes string s returns player player
local player p = playerIds.player[StringHash(s)]
local integer i = 0
if p != null then
return p
endif
if ACK_PLAYER_NAME then
loop
exitwhen i == bj_MAX_PLAYER_SLOTS
set p = Player(i)
if s == GetPlayerName(p) then
return p
endif
set i = i + 1
endloop
endif
return null
endfunction
function SavePlayerId takes string identifier, player p returns nothing
set playerIds.player[StringHash(identifier)] = p
endfunction
function RemovePlayerId takes string identifier returns nothing
call playerIds.player.remove(StringHash(identifier))
endfunction
private function IsPlaying takes player p returns boolean
return GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and /*
*/ GetPlayerController(p) == MAP_CONTROL_USER
endfunction
struct PChat
static thistype last = 0
readonly player user
readonly integer userId
readonly string str
readonly string substr
readonly integer length
readonly string array word[MAX_WORDS]
readonly integer array wordStart[MAX_WORDS]
readonly integer array wordEnd[MAX_WORDS]
readonly integer wordCount
method update takes string chatstring returns nothing
local integer i = 0
local string char = ""
local string prev = ""
loop
exitwhen i == .wordCount
set .word[i] = null
set .wordStart[i] = 0
set .wordEnd[i] = 0
set i = i + 1
endloop
set .length = StringLength(chatstring)
set .str = chatstring
set .wordCount = 0
set .wordStart[0] = 0
set i = 0
loop
exitwhen i > .length
set char = SubString(chatstring, i, i + 1)
if char != " " then
set .word[.wordCount] = .word[.wordCount] + char
elseif prev != " " then
set .wordEnd[.wordCount] = i
set .wordCount = .wordCount + 1
set .wordStart[.wordCount] = i + 1
endif
set prev = char
set i = i + 1
endloop
set .substr = SubString(.str, .wordStart[1], .length)
set .wordEnd[.wordCount] = i - 1
set .wordCount = .wordCount + 1
set thistype.last = this
endmethod
static method create takes player p, integer pid returns thistype
local thistype this = .allocate()
set this.user = p
set this.userId = pid
return this
endmethod
method destroy takes nothing returns nothing
set .user = null
call .deallocate()
endmethod
method wordLength takes integer index returns integer
return .wordEnd[index] - .wordStart[index]
endmethod
method wordLower takes integer index returns string
return StringCase(.word[index], false)
endmethod
method wordUpper takes integer index returns string
return StringCase(.word[index], true)
endmethod
endstruct
struct Command
static thistype last
readonly static thistype head = 0
readonly static thistype tail = 0
readonly thistype next
readonly thistype prev
readonly string argument
public string tooltip
private boolean enabled
private Table trgTable
private Table disabledPlayers
private integer trgSize
private static Table commandTable
private static trigger onChatTrigger
private static method create takes string cmd returns thistype
local thistype this = .allocate()
set this.trgSize = 0
set this.trgTable = Table.create()
set this.disabledPlayers = Table.create()
set this.argument = cmd
set this.enabled = true
set thistype.commandTable[StringHash(cmd)] = this
if head == 0 then
set head = this
set tail = this
else
set this.prev = tail
set tail.next = this
set tail = this
endif
return this
endmethod
method destroy takes nothing returns nothing
local integer i = 0
local trigger t
loop
exitwhen i == .trgSize
set t = .trgTable.trigger[i]
call DestroyTrigger(t)
set i = i + 1
endloop
set t = null
if this == head and this == tail then
set head = 0
set tail = 0
elseif this == head then
set head.next.prev = 0
set head = head.next
elseif this == tail then
set tail.prev.next = 0
set tail = tail.prev
else
set this.prev.next = this.next
set this.next.prev = this.prev
endif
call thistype.commandTable.remove(StringHash(this.argument))
call this.trgTable.destroy()
call this.disabledPlayers.destroy()
call this.deallocate()
endmethod
method addTrigger takes trigger t returns nothing
set .trgTable.trigger[.trgSize] = t
set .trgSize = .trgSize + 1
endmethod
method removeTrigger takes integer index returns boolean
local trigger t
if index < 0 or index >= .trgSize then
return false
endif
set t = .trgTable.trigger[index]
set .trgSize = .trgSize - 1
loop
exitwhen index == .trgSize
set .trgTable.trigger[index] = .trgTable.trigger[index + 1]
endloop
call .trgTable.trigger.remove(index)
call DestroyTrigger(t)
set t = null
return true
endmethod
static method find takes string cmd returns thistype
return thistype.commandTable[StringHash(cmd)]
endmethod
static method exists takes string cmd returns boolean
return thistype.find(cmd) != 0
endmethod
static method register takes string cmd, code c returns thistype
local trigger t = CreateTrigger()
local thistype command = thistype.commandTable[StringHash(cmd)]
if command == 0 then
set command = Command.create(cmd)
endif
call TriggerAddAction(t, c)
call command.addTrigger(t)
set t = null
return command
endmethod
static method registerForPlayer takes string cmd, code c, player whichplayer returns thistype
local thistype command = thistype.register(cmd, c)
local integer i = 0
local player p
loop
exitwhen i == bj_MAX_PLAYER_SLOTS
set p = Player(i)
if IsPlaying(p) and p != whichplayer then
set command.disabledPlayers.boolean[GetPlayerId(p)] = true
endif
set i = i + 1
endloop
return command
endmethod
static method deregister takes string cmd returns boolean
local thistype command = thistype.commandTable[StringHash(cmd)]
if command == 0 then
return false
endif
call command.destroy()
return true
endmethod
static method enableAll takes nothing returns nothing
call EnableTrigger(thistype.onChatTrigger)
endmethod
static method disableAll takes nothing returns nothing
call DisableTrigger(thistype.onChatTrigger)
endmethod
static method enablePlayer takes string cmd, player p returns nothing
call thistype.find(cmd).disabledPlayers.remove(GetPlayerId(p))
endmethod
static method disablePlayer takes string cmd, player p returns nothing
if not IsPlaying(p) then
return
endif
set thistype.find(cmd).disabledPlayers.boolean[GetPlayerId(p)] = true
endmethod
private method isDisabledForPlayer takes player p returns boolean
return .disabledPlayers.boolean.has(GetPlayerId(p))
endmethod
static method isEnabledForPlayer takes string cmd, player p returns boolean
return not thistype.find(cmd).isDisabledForPlayer(p)
endmethod
private method exec takes player p returns nothing
local integer i = 0
loop
exitwhen i == .trgSize
call TriggerExecute(.trgTable.trigger[i])
set i = i + 1
endloop
endmethod
static method enable takes string cmd returns nothing
set thistype.find(cmd).enabled = true
endmethod
static method disable takes string cmd returns nothing
set thistype.find(cmd).enabled = false
endmethod
private static method onChatEvent takes nothing returns nothing
local player p = GetTriggerPlayer()
local boolean blocked = false
call GetPlayerChat(p).update(GetEventPlayerChatString())
set Command.last = Command.find(PChat.last.word[0])
if Command.last != 0 then
if Command.last.isDisabledForPlayer(p) and not Command.last.enabled then
set blocked = true
else
call Command.last.exec(p)
endif
endif
//! runtextmacro CHAT_EVENT_MACRO("chat_event")
//! textmacro_once CHAT_EVENT_MACRO takes VAR
if blocked then
set $VAR$ = RESET_CHAT_EVENT
set $VAR$ = ON_CMD_BLOCKED
else
set $VAR$ = RESET_CHAT_EVENT
set $VAR$ = ON_CHAT_EVENT
endif
//! endtextmacro
set p = null
endmethod
private static method onLeave takes nothing returns nothing
local player p = GetTriggerPlayer()
local integer pid = GetPlayerId(p)
local PChat chat = playerchat[pid]
local thistype cmd
call playerchat.remove(pid)
call chat.destroy()
set cmd = thistype.head
loop
exitwhen cmd == 0
call cmd.disabledPlayers.remove(pid)
set cmd = cmd.next
endloop
set p = null
endmethod
private static method onInit takes nothing returns nothing
local player p
local integer i = 0
local trigger trgLeave = CreateTrigger()
set thistype.commandTable = Table.create()
set thistype.onChatTrigger = CreateTrigger()
set thistype.last = 0
set playerIds = Table.create()
set playerchat = Table.create()
loop
exitwhen i == bj_MAX_PLAYER_SLOTS
set p = Player(i)
set playerIds.player[StringHash(I2S(i + 1))] = p
if IsPlaying(p) then
call TriggerRegisterPlayerChatEvent(thistype.onChatTrigger, p, FILTER_PREFIX, false)
call TriggerRegisterPlayerEventLeave(trgLeave, p)
set playerchat[i] = PChat.create(p, i)
endif
set i = i + 1
endloop
call TriggerAddAction(thistype.onChatTrigger, function thistype.onChatEvent)
call TriggerAddAction(trgLeave, function thistype.onLeave)
set trgLeave = null
set p = null
endmethod
endstruct
endlibrary
JASS:
/*
===============================================================================================
Command Utilities version 1.3.
Latest version: hiveworkshop.com/threads/command-utilities.307554/
===============================================================================================
This libary provides a struct for each player, which stores information generated each time a
player enters a chat command. It's purpose is to make the creation of commands faster and easier
to manage by providing a few additional API functions geared towards that end.
Credits:
- Made by Pinzu
Requirements
- Table by Bribe
hiveworkshop.com/threads/snippet-new-table.188084/
Configuration
- Simply copy Bribe's Table and this library into your map
- Modify the configurables to your preference in the global block. You can add multiple command
prefixes if you scroll down to the onInit method inside Command struct.
===============================================================================================
GLOBALS
===============================================================================================
Filter prefix, determines when the LastPlayerChat should update. If set to "-" it will only fire for chat messages
with such a prefix. If you want to have multiple commands you can scroll down and add your own events manually, however
if you want to handle all chat events then set it to nothing.
private constant string FILTER_PREFIX = ""
Numbers of maximum words the system handles, should be a relatively high number.
private constant integer MAX_WORDS = 300
This is used to allow player names as valid default identification.
private constant boolean ACK_PLAYER_NAME = true
These are used for event detection
public real chat_event = -1
public constant real RESET_CHAT_EVENT = 0 Clear previous detected chat event
public constant real ON_CHAT_EVENT = 1 Triggered when a chat event is noticed by the system
public constant real ON_CMD_BLOCKED = 2 Triggered when a command is blocked from executing
===============================================================================================
FUNCTIONS
===============================================================================================
function GetPlayerChat takes player p returns PChat
Returns a struct holding the last generated chat message data from a given player
function GetLastUpdatedChat takes nothing returns PChat
Returns a struct holding the last updated chat data
function GetLastCommand takes nothing returns Command
Returns the last detected command, blocked or not
function StrIsReal takes string s returns boolean
Returns true if a string is of type real
function StrIsInt takes string s returns boolean
Returns true if a string is of type integer
function StrIsBoolean takes string s returns boolean
Returns true if a string is of type boolean
function S2B takes string s returns boolean
Returns true if a string matches "true", otherwise false.
function StrContainsDigit takes string s returns boolean
Returns true if a string contains a digit
function StrToPlayer takes string s returns player player
Converts a string identifier into a player
function SavePlayerId takes string identifier, player p returns nothing
Saves a string as a player identification
function RemovePlayerId takes string identifier returns nothing
Removes a saved player identification
===============================================================================================
STRUCT: PChat (Player Chat)
===============================================================================================
static thistype last Last updated instance reference
readonly player user The triggering user
readonly integer userId The users player id
readonly string str Entered chat string
readonly string substr Entered chat string, excluding the command
readonly integer length Length of the entered chat string
readonly string array word[MAX_WORDS] A list of words detected from the entered chat string
readonly integer array wordStart[MAX_WORDS] Starting index of a word in the entered chat string
readonly integer array wordEnd[MAX_WORDS] Ending index of a word in the entered chat string
readonly integer wordCount Number of detected words in the entered chat string
method wordLength takes integer index returns integer
returns the length of a word at a given position.
method wordLower takes integer index returns string
Returns the word as lower case.
method wordUpper takes integer index returns string
returns the word as upper case.
===============================================================================================
STRUCT: Command
===============================================================================================
static thistype last Last updated instance reference
readonly static thistype head The first command
readonly static thistype tail The last command
readonly thistype next Next command node
readonly thistype prev Previous command node
readonly string argument Registered command string
public string tooltip Tooltip used to provide information to the user
method destroy takes nothing returns nothing
Destroys the command.
method addTrigger takes trigger t returns nothing.
Adds a trigger to be executed when the command is entered
method removeTrigger takes integer index returns boolean
Removes a trigger from the command.
static method find takes string cmd returns thistype
Returns a command with matching argument .
static method exists takes string cmd returns boolean
Returns true if the command exists.
static method register takes string cmd, code c returns thistype
Registers a command with a string argument and a given function.
static method registerForPlayer takes string cmd, code c, player whichplayer returns thistype
Register a command to be enabled for only a specific player.
static method deregister takes string cmd returns boolean
Deregisters a command.
static method enableAll takes nothing returns nothing
Enables all existing commands. Does not affect commands that are disabled to specific players.
static method disableAll takes nothing returns nothing
Disables all commands.
static method enablePlayer takes string cmd, player p returns nothing
Enables a command for a given player.
static method disablePlayer takes string cmd, player p returns nothing
Disables a command for a given player.
static method isEnabledForPlayer takes string cmd, player p returns boolean
Returns true if a command is enabled for a given player.
static method enable takes string cmd returns nothing
Enables the specified command, does not affect players that are disabled.
static method disable takes string cmd returns nothing
Disables the specified command.
===============================================================================================*/
Example 1
Example 2
Note in the second example that we have registrated two functions to the same command. When the player then executes the command both of these functions will run.
Example 3
We can also register commands that start off as enabled for only one player. To enable it for others you'll have to continue reading.
JASS:
scope Hello initializer Init
private function SayHello takes nothing returns nothing
call BJDebugMsg("Hello, World!")
endfunction
private function Init takes nothing returns nothing
call Command.register("-hello", function SayHello)
endfunction
endscope
JASS:
scope Hello initializer Init
private function SpamHello takes nothing returns nothing
call BJDebugMsg("Hello Spam!")
endfunction
private function SayHello takes nothing returns nothing
call BJDebugMsg("Hello, World!")
endfunction
private function Init takes nothing returns nothing
call Command.register("-hello", function SayHello)
call Command.register("-hello" function SpamHello)
endfunction
endscope
Example 3
We can also register commands that start off as enabled for only one player. To enable it for others you'll have to continue reading.
JASS:
scope Hello initializer Init
private function SayHello takes nothing returns nothing
call BJDebugMsg("Hello, World!")
endfunction
private function Init takes nothing returns nothing
call Command.registerForPlayer("-hello", function SayHello, Player(0))
endfunction
endscope
Example 1
Using the same trigger as before. We will create the same command but this time remove it once it has fired once.
JASS:
scope Hello initializer Init
private function SayHello takes nothing returns nothing
call BJDebugMsg("Hello, World!")
call Command.deregister("-hello")
endfunction
private function Init takes nothing returns nothing
call Command.register("-hello", function SayHello)
endfunction
endscope
call Command.last.destroy()
or call Command.find("-hello").destroy()
Example 2
What if I have two triggers registrated to the same command but only want to remove one? Worry not, you simply have to remeber the index of the trigger you want removed.
JASS:
scope Hello initializer Init
private function SpamHello takes nothing returns nothing
call BJDebugMsg("Hello Spam!")
call Command.last.removeTrigger(1)
endfunction
private function SayHello takes nothing returns nothing
call BJDebugMsg("Hello, World!")
endfunction
private function Init takes nothing returns nothing
call Command.register("-hello", function SayHello)
call Command.register("-hello", function SpamHello)
endfunction
endscope
First a brief overview of the enable/disable API.
call Command.disableAll()
Disables all commands.call Command.enableAll()
Enables all commands.call Command.disable("-hello")
Disables the command "-hello".call Command.enable("-hello")
Enables the command "-hello".call Command.disablePlayer("-hello", Player(0))
Disables the "-hello" command for a Player Red.call Command.enablePlayer("-hello", Player(0))
Enables the "-hello" command for a Player Red.Command.isEnabledForPlayer("-hello", Player(0))
Returns true if "-hello" is enabled for Player Red.Example 1
Now lets take the above information and create a cooldown that limits how often a player can use the "-hello" command.
JASS:
scope Hello initializer Init
globals
private Table table
endglobals
private function EnableHelloAgain takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local player p = table.player[id]
call Command.enablePlayer("-hello", p)
call table.remove(id)
call DestroyTimer(t)
call BJDebugMsg("Hello renabled for " + GetPlayerName(p))
set p = null
set t = null
endfunction
private function SayHello takes nothing returns nothing
local timer t = CreateTimer()
local player p = GetTriggerPlayer()
call TimerStart(t, 5.0, false, function EnableHelloAgain)
call Command.disablePlayer("-hello", p)
set table.player[GetHandleId(t)] = p
set t = null
call BJDebugMsg("Hello, it's me again!")
endfunction
private function Init takes nothing returns nothing
call Command.register("-hello", function SayHello)
set table = Table.create()
endfunction
endscope
First a brief overview of the API.
static PChat last
Last updated struct instance.readonly player user
Holds the triggering player.readonly integer userId
Holds the player id of the triggering player.readonly string str
The entered chat stringreadonly string substr
The entire chat string after the command word.readonly integer length
The length of the entered chat string.readonly string array word
Found words from the entered chat string.readonly integer array wordStart
The first index of a given word.readonly integer array wordEnd
The last index of a given word.readonly integer wordCount
The number of words found in the entered chat string.method wordLength takes integer index returns integer
Returns the length of a word at a given position.method wordLower takes integer index returns string
Returns a word as lower case.method wordUpper takes integer index returns string
Returns a word as upper case.Example 1
Iterating over all the words entered by the player.
JASS:
scope ListWords initializer Init
private function ListWords takes nothing returns nothing
local PChat chat = GetLastUpdatedChat() // Alternatively chat = PChat.last
local string s = ""
local integer i = 1 // We start at 1 to exclude the command word.
loop
exitwhen i == chat.wordCount
set s = "'" + chat.word + "' "
set i = i + 1
endloop
call BJDebugMsg(GetPlayerName(chat.user) + " words: " + s)
endfunction
private function Init takes nothing returns nothing
call Command.register("-words", function ListWords)
endfunction
endscope
Creating a substring based on a combination of words using wordStart and wordEnd
JASS:
scope CombineWords initializer Init
private function CombineWordAsSubstring takes nothing returns nothing
local PChat chat = GetLastUpdatedChat()
if chat.wordCount > 1 then
call BJDebugMsg("'" + SubString(chat.str, chat.wordStart[1], chat.wordEnd[chat.wordCount - 1]) + "'") // We exclude the last word!
endif
endfunction
private function Init takes nothing returns nothing
call Command.register("-combine", function CombineWordAsSubstring)
endfunction
endscope
Per default the library recognizes player numbers such as "1" for player red and player names. If you don't wish to permit player names as identifiers you can go to the global configurable block and set the variable ACK_PLAYER_NAME to false. You can also create your own string identifiers for players or remove the default player numbers, using the following API:
function SavePlayerId takes string identifier, player p returns nothing
function RemovePlayerId takes string identifier returns nothing
function StrToPlayer takes string s returns player
Example 1
Now let's create a command for kicking players that utilizes StrToPlayer to find out which player should be dropped.
JASS:
scope KickPlayer initializer Init
private function KickPlayer takes nothing returns nothing
local PChat chat = GetLastUpdatedChat()
local player p = StrToPlayer(chat.word[1])
if p == null then
call BJDebugMsg("Invalid Player.")
return
endif
call CustomDefeatBJ(p, "You were kicked by " + GetPlayerName(chat.user) + "...")
call BJDebugMsg(GetPlayerName(p) + " was kicked by " + GetPlayerName(chat.user) + "!")
set p = null
endfunction
private function Init takes nothing returns nothing
call Command.register("-kick", function KickPlayer)
// Lets create custom identifiers
call SavePlayerId("red", Player(0))
call SavePlayerId("blue", Player(1))
// and so on...
endfunction
endscope
Example 1
In this example we will create a cheat that is the same as the CreateUnit native. We will be using an external library for string to ascii conversion to get the unit type. The rest of the functions used exists inside the library.
[Snippet] Ascii
JASS:
scope Spawn initializer Init
private function SpawnUnit takes nothing returns nothing
local PChat chat = GetLastUpdatedChat()
local real x
local real y
local real facing
local player p
local integer id
// Checking word length
if chat.wordCount < 4 then
call BJDebugMsg("Invalid command.\nHelp: " + Command.last.tooltip)
return
endif
// Getting the player
set p = StrToPlayer(chat.word[1])
if p == null then
call BJDebugMsg("Invalid player specified.\nHelp: " + Command.last.tooltip)
return
endif
// Getting the Unit Type Id
set id = S2A(chat.word[2])
if not StrIsReal(chat.word[3]) or not StrIsReal(chat.word[4]) then
call BJDebugMsg("Invalid coordinates specified.\nHelp: " + Command.last.tooltip)
return
endif
set x = S2R(chat.word[4])
set y = S2R(chat.word[5])
set facing = S2R(chat.word[6])
call CreateUnit(p, id, x, y, facing)
endfunction
private function Init takes nothing returns nothing
local Command command = Command.register("-spawn", function SpawnUnit)
set command.tooltip = "-spawn [player] [unit id] [x] [y] [facing]"
endfunction
endscope
Example 2
In this example we'll be creating a -give command for sending players gold or wood.
JASS:
scope Give initializer Init
private function Give takes nothing returns nothing
local PChat chat = GetLastUpdatedChat()
local player p2
local integer amount
local integer totalAmount
if (chat.wordCount != 4) then
call BJDebugMsg("Invalid entry.\nHelp: " + Command.last.tooltip)
return
endif
set p2 = StrToPlayer(chat.word[1])
if (p2 == null) then
call BJDebugMsg("Invalid player specified.\nHelp: " + Command.last.tooltip)
return
endif
if p2 == chat.user then
call BJDebugMsg("You can't gift yourself!")
return
endif
// The amount that wants to be given
if not StrIsInt(chat.word[2]) then
call BJDebugMsg("No amount specified.\nHelp: " + Command.last.tooltip)
return
endif
set amount = S2I(chat.word[2])
if (chat.word[3] == "gold" or chat.word[3] == "g") then
set totalAmount = GetPlayerState(p2, PLAYER_STATE_RESOURCE_GOLD)
if totalAmount < amount then
set amount = totalAmount
endif
call SetPlayerState(p2, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(p2, PLAYER_STATE_RESOURCE_GOLD) + amount)
call SetPlayerState(chat.user, PLAYER_STATE_RESOURCE_GOLD, totalAmount - amount)
call BJDebugMsg(GetPlayerName(chat.user) + " gave " + GetPlayerName(p2) + " " + I2S(amount) + " gold.")
elseif (chat.word[3] == "wood" or chat.word[3] == "lumber" or chat.word[3] == "l" or chat.word[3] == "w") then
set totalAmount = GetPlayerState(p2, PLAYER_STATE_RESOURCE_LUMBER)
if totalAmount < amount then
set amount = totalAmount
endif
call BJDebugMsg(GetPlayerName(chat.user) + " gave " + GetPlayerName(p2) + " " + I2S(amount) + " lumber.")
call SetPlayerState(chat.user, PLAYER_STATE_RESOURCE_LUMBER, totalAmount - amount)
call SetPlayerState(p2, PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(p2, PLAYER_STATE_RESOURCE_LUMBER) + amount)
else
call BJDebugMsg("Invalid resource specified")
endif
endfunction
private function Init takes nothing returns nothing
local Command command = Command.register("-give", function Give)
set command.tooltip = "-give [player] [amount] [resource]"
endfunction
endscope
Example 1
In this example we'll be creating a "-commands" command to get all available commands for the triggering player. But you could just as well use this to put it in a quest log or anything else really.
JASS:
scope Commands initializer Init
private function ShowPlayerCommands takes nothing returns nothing
local PChat chat = GetLastUpdatedChat()
local Command cmd = Command.head
local string s = ""
loop
exitwhen cmd == 0
if Command.isEnabledForPlayer(cmd.argument, chat.user) then
set s = s + cmd.tooltip + "\n"
endif
set cmd = cmd.next
endloop
call BJDebugMsg("Commands:\n" + s)
endfunction
private function YesReally takes nothing returns nothing
call DoNothing()
endfunction
private function Init takes nothing returns nothing
local Command cmd = Command.register("-commands", function ShowPlayerCommands)
set cmd.tooltip = "-commands"
set cmd = Command.register("-kick", function YesReally)
set cmd.tooltip = "-kick [player]"
set cmd = Command.register("-name", function YesReally)
set cmd.tooltip = "-name [player name]"
set cmd = Command.register("-give", function YesReally)
set cmd.tooltip = "-give [player] [amount] [resource]"
set cmd = Command.register("-spawn", function YesReally)
set cmd.tooltip = "-spawn [player] [unit type] [x] [y] [facing]"
set cmd = Command.register("-hello", function YesReally)
set cmd.tooltip = "-hello"
call Command.disablePlayer("-hello", Player(0))
endfunction
endscope
Finally, in this example you'll learn how to use the provided real variable events to process all entered chat messages and detect commands that were blocked from execution. This can be used for creating a chat system or displaying error messages for blocked commands.
Step by step:
1) Change the configurable: Set FILTER_PREFIX = ""
2) Scroll down in the library code until you find the static method "onChatEvent" inside the Command struct. Then change the variable (chat_event) inside the textmacros to your global variable.
3) Implement it in your chat trigger. It should look something like this:
JASS:
scope ChatEvent initializer Init
private function OnChatEvent takes nothing returns nothing
local PChat chat = GetLastUpdatedChat()
local Command cmd = GetLastCommand()
if cmd != 0 then
call BJDebugMsg("Executed command: " + cmd.argument)
else
call BJDebugMsg(GetPlayerName(chat.user) + ": " + chat.str)
endif
endfunction
private function OnChatBlocked takes nothing returns nothing
local Command cmd = GetLastCommand()
local PChat chat = GetLastUpdatedChat()
call BJDebugMsg(GetPlayerName(chat.user) + " cannot execute command: " + cmd.argument + "!")
endfunction
private function Init takes nothing returns nothing
local trigger trgOnChatEvent = CreateTrigger()
local trigger trgOnCmdBlocked = CreateTrigger()
call TriggerRegisterVariableEvent(trgOnChatEvent, "udg_chat_event", EQUAL, 1)
call TriggerRegisterVariableEvent(trgOnCmdBlocked, "udg_chat_event", EQUAL, 2)
call TriggerAddAction(trgOnChatEvent, function OnChatEvent)
call TriggerAddAction(trgOnCmdBlocked, function OnChatBlocked)
set trgOnChatEvent = null
set trgOnCmdBlocked = null
endfunction
endscope
Last edited: