Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # #########################################################################################
- # Kill Leaderboard Examples by AsuDev
- # Requirements: Skript for your version, Skript-Mirror 2.0.0+, SkQuery-Lime
- # Versions: 1.8.8 - 1.14.4
- # #########################################################################################
- # EXTRA INFORMATION
- # The sorting method used in this script can sort up to 50,000 values a second!
- # This script is just a collection of examples of making a toplist!
- # You may edit this script however you want and you can make whatever you want with it.
- # THIS CURRENT VERSION IS FOR SKRIPT 2.3.6 AND LOWER! TO MAKE IT COMPATIBLE WITH THE HIGHER
- # VERSIONS, YOU MUST CHANGE THE SEND MESSAGE TO "send formatted" instead of "send" for the
- # json formatting. This will not throw an error, but the json formatting will be messed up
- # when using Skript 2.3.7+
- # #########################################################################################
- # CREDITS
- # AsuDev for making the script and all of the examples.
- # EWS for making this sorting algorithm for skript variables in skript-mirror
- # #########################################################################################
- # List of java class imports
- import:
- java.util.ArrayList
- java.util.Collections
- java.util.Map$Entry
- ch.njol.skript.variables.Variables
- java.lang.System
- org.json.simple.JSONValue
- # These options are for if you are going to actually use this script instead
- # of taking from it and making your own thing. You can experiment with these
- # and use or change whatever you want.
- options:
- updaterBreak: 15 minutes # How often to update the leaderboard automatically
- indexesPerPage: 10 # Amount of players to show per page in the toplist
- FirstPlaceFormat: &6&l # Format of first place
- SecondPlaceFormat: &b&l # Format of second place
- ThirdPlaceFormat: &2&l # Format of third place
- OtherPlaceFormat: &3 # Format of everything else
- Splitter: - # What to split the player data with when sorting players
- OutputFormat: @place-@index-@value # The output for sorting players / Make sure splitter is correct with this
- ChatBorder: &8&m----------------------------------------------------
- # @StartIndex is the value the list starts at / @EndIndex is the where the page ends / @LastUpdated is the last time the leaderboard was updated
- ChatOutputHeader: &eTop Killers &8- &7Showing &6@StartIndex-@EndIndex &8- &7Last Updated: &b@LastUpdated ago # The header of the leaderboard command
- # @place is the place the player is in / @index is the player name / @value is the amount of kills they have
- ChatOutputFormat: &8➵ @place &7@index &8- &a@value Kills # The chat output for the leaderboard command for each player
- # #########################################################################################
- # For null values when sorting
- # Gets the name of an offline player based on UUID
- function getOfflinePlayerName(uuid: text) :: string:
- replace all "-" with "" in {_uuid}
- set {_jsonInfo} to text from "https://api.mojang.com/user/profiles/%{_uuid}%/names"
- set {_nameValue} to JSONValue.parseWithException({_jsonInfo})
- set {_player} to {_nameValue}.get({_nameValue}.size()-1).toString()
- set {_nameObject} to JSONValue.parseWithException({_player})
- return {_nameObject}.get("name").toString()
- # #########################################################################################
- # EXPRESSIONS
- # Expression used to replace multiple values within a string at once.
- # Original version made by EWS
- expression replace values %strings% with %strings% in %string%:
- get:
- set {_string} to expression-3
- loop expressions-1:
- add 1 to {_index}
- replace all "%loop-value%" with "%{_index}th element of expressions-2%" in {_string}
- return {_string}
- # Expression used for sorting. Uses java collections for sorting and is very fast.
- # Original version made by EWS, edited by AsuDev.
- plural expression [the] (1¦(highest|top)|2¦(lowest|last)) %integer% values of %objects% [formatted] as %string%:
- get:
- set {_list} to new ArrayList(Variables.getVariable(raw expressions-2.getName().toString(event), event, raw expressions-2.isLocal()).entrySet())
- {_list}.sort(Entry.comparingByValue())
- if parse mark = 1:
- Collections.reverse({_list})
- loop ...{_list}:
- # "%loop-value.getValue()%" is not "0"
- add 1 to {_index}
- if "%(loop-value.getKey()) parsed as offline player%" is not "null":
- set {_sorted::%{_index}%} to replace values "@place", "@index" and "@value" with "%{_index}%", "%(loop-value.getKey()) parsed as offline player%" and "%loop-value.getValue()%" in expression-3
- else:
- loop {CachedOfflinePlayers::*}:
- if loop-value-2 contains "^%loop-value-1.getKey()%":
- set {_v::*} to loop-value-2 split by "^"
- set {_name} to {_v::1}
- set {_sorted::%{_index}%} to replace values "@place", "@index" and "@value" with "%{_index}%", {_name} and "%loop-value-1.getValue()%" in expression-3
- set {_continue} to false
- if {_continue} is not set:
- set {_name} to getOfflinePlayerName(loop-value.getKey())
- set {_sorted::%{_index}%} to replace values "@place", "@index" and "@value" with "%{_index}%", {_name} and "%loop-value.getValue()%" in expression-3
- message "&cError when getting name from uuid '%loop-value.getKey()%'. Retrieving name from Mojangs database may severely slow down the sorting time! This should not occur with this uuid again as data is now stored for this uuid." to console
- add "%{_name}%^%loop-value-1.getKey()%" to {CachedOfflinePlayers::*}
- delete {_continue} and {_name} and {_v::*}
- {_index} = expression-1
- stop loop
- return {_sorted::*}
- # #########################################################################################
- # EXAMPLE EVENTS / FUNCTIONS
- # Updates the leaderboard
- function updateKillsLeaderboard(senders: objects):
- delete {KillLB::*}
- set {_timeNow} to ceil(System.currentTimeMillis())
- loop {_senders::*}:
- send "&7Updating the Kill leaderboard..." to loop-value
- set {KillLB::*} to the highest (size of {Kills::*}) values of {Kills::*} as "{@OutputFormat}"
- set {_timeAfter} to (ceil(System.currentTimeMillis()) - {_timeNow})
- loop {_senders::*}:
- send "&7Update complete. The update took &b%{_timeAfter}%ms&7." to loop-value
- set {LastLeaderboardUpdate} to ceil(System.currentTimeMillis())
- # Gets the ordinal string of an integer
- function ordinalNumber(i: integer) :: string:
- set {_lastDigit} to mod({_i}, 10)
- set {_lastTwoDigits} to mod({_i}, 100)
- if {_lastTwoDigits} is between 10 and 20:
- return "%{_i}%th"
- else if {_lastDigit} is 1:
- return "%{_i}%st"
- else if {_lastDigit} is 2:
- return "%{_i}%nd"
- else if {_lastDigit} is 3:
- return "%{_i}%rd"
- else:
- return "%{_i}%th"
- # Gets a player's place on the leaderboard and formats it into an ordinal ranking format
- function getKillPlacing(p: offline player) :: string:
- loop {KillLB::*}:
- if loop-value contains "-%{_p}%-":
- set {_placing} to loop-index parsed as integer
- if {_placing} is 1:
- return "{@FirstPlaceFormat}%ordinalNumber(1)%."
- else if {_placing} is 2:
- return "{@SecondPlaceFormat}%ordinalNumber(2)%."
- else if {_placing} is 3:
- return "{@ThirdPlaceFormat}%ordinalNumber(3)%."
- else:
- return "{@OtherPlaceFormat}%ordinalNumber({_placing})%."
- stop
- # Converts an integer into an ordinal ranking format by integer
- function ordinalNumberRankFormat(placing: integer) :: string:
- if {_placing} is 1:
- return "{@FirstPlaceFormat}%ordinalNumber(1)%."
- else if {_placing} is 2:
- return "{@SecondPlaceFormat}%ordinalNumber(2)%."
- else if {_placing} is 3:
- return "{@ThirdPlaceFormat}%ordinalNumber(3)%."
- else:
- return "{@OtherPlaceFormat}%ordinalNumber({_placing})%."
- # Example calculation of KDR of a player
- function calculateKDR(p: offline player) :: string:
- set {_uuid} to uuid of {_p}
- set {_kills} to {Kills::%{_uuid}%}
- set {_deaths} to {Deaths::%{_uuid}%}
- if {_kills} and {_deaths} is 0:
- return "&60"
- if {_kills} is not 0:
- if {_deaths} is 0:
- add 1 to {_deaths}
- return "&6%{_kills}/{_deaths}%"
- # Formats seconds into a nice, more readable time.
- function formatTime(i: number) :: string:
- set {_s} to "s"
- set {_days} to floor({_i} / 86400)
- set {_hours} to floor({_i} / 3600)
- set {_minutes} to floor((mod({_i}, 3600)) / 60)
- set {_seconds} to floor(mod({_i}, 3600))
- set {_seconds} to floor(mod({_seconds}, 60))
- set {_format} to ""
- if {_days} is not 0:
- set {_format} to "%{_days}%d "
- if {_hours} is not 0:
- set {_format} to "%{_format}%%{_hours}%h "
- if {_minutes} is not 0:
- set {_format} to "%{_format}%%{_minutes}%m "
- return "%{_format}%%{_seconds}%%{_s}%"
- # Example scheduler to update the leaderboard
- every {@updaterBreak}:
- updateKillsLeaderboard(console)
- loop all players:
- if loop-player has permission "boardupdator":
- message "&7The Kills leaderboard has just been updated." to loop-player
- # Example, set the players stats when they join
- on join:
- {Kills::%uuid of player%} is not set
- set {Kills::%uuid of player%} to 0
- set {Deaths::%uuid of player%} to 0
- # Example event to add kills/deaths to a player
- on death of player:
- add 1 to {Deaths::%uuid of victim%}
- attacker is a player
- add 1 to {Kills::%uuid of attacker%}
- # #########################################################################################
- # EXAMPLE COMMANDS
- # Example, manual command for updating the kills leaderboard
- command /updateKillsLeaderboard:
- permission: leaderboard.update
- permission message: &cYou do not have permission to execute this command.
- trigger:
- updateKillsLeaderboard(player and console)
- # A cache for offline players in case sorting returns a null value
- command /cachedofflineplayers:
- aliases: coplayers
- permission: cachedview.admin
- trigger:
- message "&6Cached Offline Players"
- loop {CachedOfflinePlayers::*}:
- set {_values::*} to loop-value split by "^"
- message "&8- &b%{_values::1}% &8(&e%{_values::2}%&8)"
- # Example, K/D stats for a specified player
- command /kills [<offline player=%player%>]:
- aliases: deaths, kdr
- trigger:
- if {Kills::%uuid of arg 1%} and {Deaths::%uuid of arg 1%} is set:
- message "&e%arg 1%'s K/D Stats"
- message "&7Kills: &a%{Kills::%uuid of arg 1%}%"
- message "&7Deaths: &c%{Deaths::%uuid of arg 1%}%"
- message "&7KDR: &a%{Kills::%uuid of arg 1%}%&7/&c%{Deaths::%uuid of arg 1%}% &7= %calculateKDR(arg 1)%"
- if getKillPlacing(arg 1) is not set:
- message "&7Leaderboard: &3Not on leaderboard."
- else:
- message "&7Leaderboard: %getKillPlacing(arg 1)%"
- else:
- message "&cThat player has no stats logged for kills or deaths."
- # Example, Get a player's placing index
- command /placing [<offline player=%player%>]:
- trigger:
- if {Kills::%uuid of arg 1%} and {Deaths::%uuid of arg 1%} is set:
- if getKillPlacing(arg 1) is not set:
- message "&e%arg 1% &7is currently not on the kill leaderboard."
- else:
- message "&e%arg 1% &7is currently %getKillPlacing(arg 1)% &7on the kill leaderboard."
- else:
- message "&cThat player has no stats logged for kills or deaths."
- # Example, Get a player at a specified placing
- command /place [<integer=1>]:
- trigger:
- if arg 1 is less than or equal to 0:
- message "&cInvalid placing. Please specify a number greater than 0."
- stop
- if size of {KillLB::*} is less than arg 1:
- message "&cInvalid placing. The number you specified exceeded the total amount of players in the leaderboard. The max is currently %size of {KillLB::*}%."
- stop
- set {_placing::*} to {KillLB::%arg 1%} split by "{@Splitter}"
- set {_p} to {_placing::2} parsed as offline player
- set {_placing} to ordinalNumberRankFormat({_placing::1} parsed as integer)
- message "&7The player in %{_placing}% &7place on the kill leaderboard is &e%{_p}%&7."
- # Example, Leaderboard command
- command /topkills [<integer=1>]:
- aliases: topk, topkiller, topkillers, toplb, topleaderboard
- trigger:
- if arg 1 is less than or equal to 0:
- message "&cYou must specify a page over 0."
- stop
- set {_lastUpdated} to formatTime((ceil(System.currentTimeMillis()) - {LastLeaderboardUpdate}) / 1000)
- set {_showPerPage} to {@indexesPerPage}
- set {_indexesToShow} to arg 1 * {_showPerPage}
- set {_startingIndex} to {_indexesToShow} - ({_showPerPage} - 1)
- set {_maxpage} to ceil(size of {KillLB::*} / {_showPerPage})
- if arg 1 is {_maxpage}:
- set {_showingMax} to size of {KillLB::*}
- else:
- set {_showingMax} to {_indexesToShow}
- if {KillLB::%{_startingIndex}%} is not set:
- message "&cThe page you specified wasn't found. Valid pages are 1-%{_maxpage}%."
- stop
- message "{@ChatBorder}"
- message replace values "@StartIndex", "@EndIndex" and "@LastUpdated" with "%{_indexesToShow} - ({_showPerPage} - 1)%", "%{_showingMax}%" and "%{_lastUpdated}%" in "{@ChatOutputHeader}"
- message "{@ChatBorder}"
- #message ""
- loop {KillLB::*}:
- if (loop-index parsed as integer) is between {_startingIndex} and {_indexesToShow}:
- set {_info::*} to loop-value split by "{@Splitter}"
- set {_placing} to ordinalNumberRankFormat({_info::1} parsed as integer)
- set {_p} to {_info::2} parsed as offline player
- set {_uuid} to uuid of {_p}
- set {_format} to replace values "@place", "@index", "@value" with "%{_placing}%", "%{_info::2}%", "%{_info::3}%" in "{@ChatOutputFormat}"
- send " <tooltip:&e%{_p}%'s K/D Stats%nl%&7Kills: &a%{Kills::%{_uuid}%}%%nl%&7Deaths: &c%{Deaths::%{_uuid}%}%%nl%&7KDR: &a%{Kills::%{_uuid}%}%&7/&c%{Deaths::%{_uuid}%}% &7= %calculateKDR({_p})%>%{_format}%&r" to player
- delete {_info::*} and {_placing} and {_p} and {_uuid} and {_format}
- #message ""
- message " <tooltip:&eClick to go back a page.><cmd:/topkills %arg 1 - 1%>&7←&r <tooltip:&eClick to go forward one page.><cmd:/topkills %arg 1 + 1%>&7→&r"
- message "{@ChatBorder}"
- # Example, Admin command for manipulating stats of players
- command /killsadmin [<text>] [<text>] [<offline player>] [<integer>]:
- permission: killsadmin
- permission message: &cYou do not have permission to use this command.
- aliases: kadmin, killadmin
- trigger:
- if arg 1 is not set:
- message "&fSets the amount of kills or deaths a player has."
- message "&f/killsadmin set kills,deaths <player> <amount>"
- message "&fAdds to the kills or deaths a player has."
- message "&f/killsadmin add kills,deaths <player> <amount>"
- message "&fRemoves from the amount of kills or deaths a player has."
- message "&f/killsadmin remove kills,deaths <player> <amount>"
- stop
- if arg 1 and arg 2 and arg 3 and arg 4 is set:
- if arg 2 is "kills" or "deaths":
- if arg 4 is greater than or equal to 0:
- if arg 1 is "set":
- if {%arg 2%::%uuid of arg 3%} is not set:
- set {Kills::%uuid of arg 3%} to 0
- set {Deaths::%uuid of arg 3%} to 0
- set {%arg 2%::%uuid of arg 3%} to arg 4
- message "&7You set the &c%arg 2% &7value of &b%arg 3% &7to &e%arg 4%&7."
- else if arg 1 is "add":
- if {%arg 2%::%uuid of arg 3%} is not set:
- set {Kills::%uuid of arg 3%} to 0
- set {Deaths::%uuid of arg 3%} to 0
- add arg 4 to {%arg 2%::%uuid of arg 3%}
- message "&7You added &e%arg 4% &7to the &c%arg 2% &7value of &b%arg 3%&7."
- else if arg 1 is "remove":
- if {%arg 2%::%uuid of arg 3%} is not set:
- set {Kills::%uuid of arg 3%} to 0
- set {Deaths::%uuid of arg 3%} to 0
- remove arg 4 from {%arg 2%::%uuid of arg 3%}
- message "&7You removed &e%arg 4% &7from the &c%arg 2% &7value of &b%arg 3%&7."
- if {%arg 2%::%uuid of arg 3%} is less than 0:
- set {%arg 2%::%uuid of arg 3%} to 0
- else:
- make player execute command "killsadmin"
- else:
- message "&cYou must specify an amount above or equal to 0."
- else:
- message "&cYou must specify either kills or deaths."
- else:
- make player execute command "killsadmin"
- # #########################################################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement