Advertisement
Guest User

Untitled

a guest
Feb 25th, 2020
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.37 KB | None | 0 0
  1. # #########################################################################################
  2.  
  3. # Kill Leaderboard Examples by AsuDev
  4. # Requirements: Skript for your version, Skript-Mirror 2.0.0+, SkQuery-Lime
  5. # Versions: 1.8.8 - 1.14.4
  6.  
  7. # #########################################################################################
  8.  
  9. # EXTRA INFORMATION
  10.  
  11. # The sorting method used in this script can sort up to 50,000 values a second!
  12. # This script is just a collection of examples of making a toplist!
  13. # You may edit this script however you want and you can make whatever you want with it.
  14.  
  15. # THIS CURRENT VERSION IS FOR SKRIPT 2.3.6 AND LOWER! TO MAKE IT COMPATIBLE WITH THE HIGHER
  16. # VERSIONS, YOU MUST CHANGE THE SEND MESSAGE TO "send formatted" instead of "send" for the
  17. # json formatting. This will not throw an error, but the json formatting will be messed up
  18. # when using Skript 2.3.7+
  19.  
  20. # #########################################################################################
  21.  
  22. # CREDITS
  23.  
  24. # AsuDev for making the script and all of the examples.
  25. # EWS for making this sorting algorithm for skript variables in skript-mirror
  26.  
  27. # #########################################################################################
  28.  
  29. # List of java class imports
  30. import:
  31. java.util.ArrayList
  32. java.util.Collections
  33. java.util.Map$Entry
  34. ch.njol.skript.variables.Variables
  35. java.lang.System
  36. org.json.simple.JSONValue
  37.  
  38. # These options are for if you are going to actually use this script instead
  39. # of taking from it and making your own thing. You can experiment with these
  40. # and use or change whatever you want.
  41. options:
  42. updaterBreak: 15 minutes # How often to update the leaderboard automatically
  43. indexesPerPage: 10 # Amount of players to show per page in the toplist
  44. FirstPlaceFormat: &6&l # Format of first place
  45. SecondPlaceFormat: &b&l # Format of second place
  46. ThirdPlaceFormat: &2&l # Format of third place
  47. OtherPlaceFormat: &3 # Format of everything else
  48. Splitter: - # What to split the player data with when sorting players
  49. OutputFormat: @place-@index-@value # The output for sorting players / Make sure splitter is correct with this
  50. ChatBorder: &8&m----------------------------------------------------
  51.  
  52. # @StartIndex is the value the list starts at / @EndIndex is the where the page ends / @LastUpdated is the last time the leaderboard was updated
  53. ChatOutputHeader: &eTop Killers &8- &7Showing &6@StartIndex-@EndIndex &8- &7Last Updated: &b@LastUpdated ago # The header of the leaderboard command
  54. # @place is the place the player is in / @index is the player name / @value is the amount of kills they have
  55. ChatOutputFormat: &8➵ @place &7@index &8- &a@value Kills # The chat output for the leaderboard command for each player
  56.  
  57. # #########################################################################################
  58.  
  59. # For null values when sorting
  60. # Gets the name of an offline player based on UUID
  61. function getOfflinePlayerName(uuid: text) :: string:
  62. replace all "-" with "" in {_uuid}
  63. set {_jsonInfo} to text from "https://api.mojang.com/user/profiles/%{_uuid}%/names"
  64. set {_nameValue} to JSONValue.parseWithException({_jsonInfo})
  65. set {_player} to {_nameValue}.get({_nameValue}.size()-1).toString()
  66. set {_nameObject} to JSONValue.parseWithException({_player})
  67. return {_nameObject}.get("name").toString()
  68.  
  69. # #########################################################################################
  70.  
  71. # EXPRESSIONS
  72.  
  73. # Expression used to replace multiple values within a string at once.
  74. # Original version made by EWS
  75. expression replace values %strings% with %strings% in %string%:
  76. get:
  77. set {_string} to expression-3
  78. loop expressions-1:
  79. add 1 to {_index}
  80. replace all "%loop-value%" with "%{_index}th element of expressions-2%" in {_string}
  81. return {_string}
  82.  
  83. # Expression used for sorting. Uses java collections for sorting and is very fast.
  84. # Original version made by EWS, edited by AsuDev.
  85. plural expression [the] (1¦(highest|top)|2¦(lowest|last)) %integer% values of %objects% [formatted] as %string%:
  86. get:
  87. set {_list} to new ArrayList(Variables.getVariable(raw expressions-2.getName().toString(event), event, raw expressions-2.isLocal()).entrySet())
  88. {_list}.sort(Entry.comparingByValue())
  89. if parse mark = 1:
  90. Collections.reverse({_list})
  91. loop ...{_list}:
  92. # "%loop-value.getValue()%" is not "0"
  93. add 1 to {_index}
  94. if "%(loop-value.getKey()) parsed as offline player%" is not "null":
  95. 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
  96. else:
  97. loop {CachedOfflinePlayers::*}:
  98. if loop-value-2 contains "^%loop-value-1.getKey()%":
  99. set {_v::*} to loop-value-2 split by "^"
  100. set {_name} to {_v::1}
  101. set {_sorted::%{_index}%} to replace values "@place", "@index" and "@value" with "%{_index}%", {_name} and "%loop-value-1.getValue()%" in expression-3
  102. set {_continue} to false
  103. if {_continue} is not set:
  104. set {_name} to getOfflinePlayerName(loop-value.getKey())
  105. set {_sorted::%{_index}%} to replace values "@place", "@index" and "@value" with "%{_index}%", {_name} and "%loop-value.getValue()%" in expression-3
  106. 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
  107. add "%{_name}%^%loop-value-1.getKey()%" to {CachedOfflinePlayers::*}
  108. delete {_continue} and {_name} and {_v::*}
  109. {_index} = expression-1
  110. stop loop
  111. return {_sorted::*}
  112.  
  113. # #########################################################################################
  114.  
  115. # EXAMPLE EVENTS / FUNCTIONS
  116.  
  117. # Updates the leaderboard
  118. function updateKillsLeaderboard(senders: objects):
  119. delete {KillLB::*}
  120. set {_timeNow} to ceil(System.currentTimeMillis())
  121. loop {_senders::*}:
  122. send "&7Updating the Kill leaderboard..." to loop-value
  123. set {KillLB::*} to the highest (size of {Kills::*}) values of {Kills::*} as "{@OutputFormat}"
  124. set {_timeAfter} to (ceil(System.currentTimeMillis()) - {_timeNow})
  125. loop {_senders::*}:
  126. send "&7Update complete. The update took &b%{_timeAfter}%ms&7." to loop-value
  127. set {LastLeaderboardUpdate} to ceil(System.currentTimeMillis())
  128.  
  129. # Gets the ordinal string of an integer
  130. function ordinalNumber(i: integer) :: string:
  131. set {_lastDigit} to mod({_i}, 10)
  132. set {_lastTwoDigits} to mod({_i}, 100)
  133. if {_lastTwoDigits} is between 10 and 20:
  134. return "%{_i}%th"
  135. else if {_lastDigit} is 1:
  136. return "%{_i}%st"
  137. else if {_lastDigit} is 2:
  138. return "%{_i}%nd"
  139. else if {_lastDigit} is 3:
  140. return "%{_i}%rd"
  141. else:
  142. return "%{_i}%th"
  143.  
  144. # Gets a player's place on the leaderboard and formats it into an ordinal ranking format
  145. function getKillPlacing(p: offline player) :: string:
  146. loop {KillLB::*}:
  147. if loop-value contains "-%{_p}%-":
  148. set {_placing} to loop-index parsed as integer
  149. if {_placing} is 1:
  150. return "{@FirstPlaceFormat}%ordinalNumber(1)%."
  151. else if {_placing} is 2:
  152. return "{@SecondPlaceFormat}%ordinalNumber(2)%."
  153. else if {_placing} is 3:
  154. return "{@ThirdPlaceFormat}%ordinalNumber(3)%."
  155. else:
  156. return "{@OtherPlaceFormat}%ordinalNumber({_placing})%."
  157. stop
  158.  
  159. # Converts an integer into an ordinal ranking format by integer
  160. function ordinalNumberRankFormat(placing: integer) :: string:
  161. if {_placing} is 1:
  162. return "{@FirstPlaceFormat}%ordinalNumber(1)%."
  163. else if {_placing} is 2:
  164. return "{@SecondPlaceFormat}%ordinalNumber(2)%."
  165. else if {_placing} is 3:
  166. return "{@ThirdPlaceFormat}%ordinalNumber(3)%."
  167. else:
  168. return "{@OtherPlaceFormat}%ordinalNumber({_placing})%."
  169.  
  170. # Example calculation of KDR of a player
  171. function calculateKDR(p: offline player) :: string:
  172. set {_uuid} to uuid of {_p}
  173. set {_kills} to {Kills::%{_uuid}%}
  174. set {_deaths} to {Deaths::%{_uuid}%}
  175. if {_kills} and {_deaths} is 0:
  176. return "&60"
  177. if {_kills} is not 0:
  178. if {_deaths} is 0:
  179. add 1 to {_deaths}
  180. return "&6%{_kills}/{_deaths}%"
  181.  
  182. # Formats seconds into a nice, more readable time.
  183. function formatTime(i: number) :: string:
  184. set {_s} to "s"
  185. set {_days} to floor({_i} / 86400)
  186. set {_hours} to floor({_i} / 3600)
  187. set {_minutes} to floor((mod({_i}, 3600)) / 60)
  188. set {_seconds} to floor(mod({_i}, 3600))
  189. set {_seconds} to floor(mod({_seconds}, 60))
  190. set {_format} to ""
  191. if {_days} is not 0:
  192. set {_format} to "%{_days}%d "
  193. if {_hours} is not 0:
  194. set {_format} to "%{_format}%%{_hours}%h "
  195. if {_minutes} is not 0:
  196. set {_format} to "%{_format}%%{_minutes}%m "
  197. return "%{_format}%%{_seconds}%%{_s}%"
  198.  
  199. # Example scheduler to update the leaderboard
  200. every {@updaterBreak}:
  201. updateKillsLeaderboard(console)
  202. loop all players:
  203. if loop-player has permission "boardupdator":
  204. message "&7The Kills leaderboard has just been updated." to loop-player
  205.  
  206. # Example, set the players stats when they join
  207. on join:
  208. {Kills::%uuid of player%} is not set
  209. set {Kills::%uuid of player%} to 0
  210. set {Deaths::%uuid of player%} to 0
  211.  
  212. # Example event to add kills/deaths to a player
  213. on death of player:
  214. add 1 to {Deaths::%uuid of victim%}
  215. attacker is a player
  216. add 1 to {Kills::%uuid of attacker%}
  217.  
  218. # #########################################################################################
  219.  
  220. # EXAMPLE COMMANDS
  221.  
  222. # Example, manual command for updating the kills leaderboard
  223. command /updateKillsLeaderboard:
  224. permission: leaderboard.update
  225. permission message: &cYou do not have permission to execute this command.
  226. trigger:
  227. updateKillsLeaderboard(player and console)
  228.  
  229. # A cache for offline players in case sorting returns a null value
  230. command /cachedofflineplayers:
  231. aliases: coplayers
  232. permission: cachedview.admin
  233. trigger:
  234. message "&6Cached Offline Players"
  235. loop {CachedOfflinePlayers::*}:
  236. set {_values::*} to loop-value split by "^"
  237. message "&8- &b%{_values::1}% &8(&e%{_values::2}%&8)"
  238.  
  239. # Example, K/D stats for a specified player
  240. command /kills [<offline player=%player%>]:
  241. aliases: deaths, kdr
  242. trigger:
  243. if {Kills::%uuid of arg 1%} and {Deaths::%uuid of arg 1%} is set:
  244. message "&e%arg 1%'s K/D Stats"
  245. message "&7Kills: &a%{Kills::%uuid of arg 1%}%"
  246. message "&7Deaths: &c%{Deaths::%uuid of arg 1%}%"
  247. message "&7KDR: &a%{Kills::%uuid of arg 1%}%&7/&c%{Deaths::%uuid of arg 1%}% &7= %calculateKDR(arg 1)%"
  248. if getKillPlacing(arg 1) is not set:
  249. message "&7Leaderboard: &3Not on leaderboard."
  250. else:
  251. message "&7Leaderboard: %getKillPlacing(arg 1)%"
  252. else:
  253. message "&cThat player has no stats logged for kills or deaths."
  254.  
  255. # Example, Get a player's placing index
  256. command /placing [<offline player=%player%>]:
  257. trigger:
  258. if {Kills::%uuid of arg 1%} and {Deaths::%uuid of arg 1%} is set:
  259. if getKillPlacing(arg 1) is not set:
  260. message "&e%arg 1% &7is currently not on the kill leaderboard."
  261. else:
  262. message "&e%arg 1% &7is currently %getKillPlacing(arg 1)% &7on the kill leaderboard."
  263. else:
  264. message "&cThat player has no stats logged for kills or deaths."
  265.  
  266. # Example, Get a player at a specified placing
  267. command /place [<integer=1>]:
  268. trigger:
  269. if arg 1 is less than or equal to 0:
  270. message "&cInvalid placing. Please specify a number greater than 0."
  271. stop
  272. if size of {KillLB::*} is less than arg 1:
  273. message "&cInvalid placing. The number you specified exceeded the total amount of players in the leaderboard. The max is currently %size of {KillLB::*}%."
  274. stop
  275. set {_placing::*} to {KillLB::%arg 1%} split by "{@Splitter}"
  276. set {_p} to {_placing::2} parsed as offline player
  277. set {_placing} to ordinalNumberRankFormat({_placing::1} parsed as integer)
  278. message "&7The player in %{_placing}% &7place on the kill leaderboard is &e%{_p}%&7."
  279.  
  280. # Example, Leaderboard command
  281. command /topkills [<integer=1>]:
  282. aliases: topk, topkiller, topkillers, toplb, topleaderboard
  283. trigger:
  284. if arg 1 is less than or equal to 0:
  285. message "&cYou must specify a page over 0."
  286. stop
  287. set {_lastUpdated} to formatTime((ceil(System.currentTimeMillis()) - {LastLeaderboardUpdate}) / 1000)
  288. set {_showPerPage} to {@indexesPerPage}
  289. set {_indexesToShow} to arg 1 * {_showPerPage}
  290. set {_startingIndex} to {_indexesToShow} - ({_showPerPage} - 1)
  291. set {_maxpage} to ceil(size of {KillLB::*} / {_showPerPage})
  292. if arg 1 is {_maxpage}:
  293. set {_showingMax} to size of {KillLB::*}
  294. else:
  295. set {_showingMax} to {_indexesToShow}
  296. if {KillLB::%{_startingIndex}%} is not set:
  297. message "&cThe page you specified wasn't found. Valid pages are 1-%{_maxpage}%."
  298. stop
  299. message "{@ChatBorder}"
  300. message replace values "@StartIndex", "@EndIndex" and "@LastUpdated" with "%{_indexesToShow} - ({_showPerPage} - 1)%", "%{_showingMax}%" and "%{_lastUpdated}%" in "{@ChatOutputHeader}"
  301. message "{@ChatBorder}"
  302. #message ""
  303. loop {KillLB::*}:
  304. if (loop-index parsed as integer) is between {_startingIndex} and {_indexesToShow}:
  305. set {_info::*} to loop-value split by "{@Splitter}"
  306. set {_placing} to ordinalNumberRankFormat({_info::1} parsed as integer)
  307. set {_p} to {_info::2} parsed as offline player
  308. set {_uuid} to uuid of {_p}
  309. set {_format} to replace values "@place", "@index", "@value" with "%{_placing}%", "%{_info::2}%", "%{_info::3}%" in "{@ChatOutputFormat}"
  310. 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
  311. delete {_info::*} and {_placing} and {_p} and {_uuid} and {_format}
  312. #message ""
  313. 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"
  314. message "{@ChatBorder}"
  315.  
  316. # Example, Admin command for manipulating stats of players
  317. command /killsadmin [<text>] [<text>] [<offline player>] [<integer>]:
  318. permission: killsadmin
  319. permission message: &cYou do not have permission to use this command.
  320. aliases: kadmin, killadmin
  321. trigger:
  322. if arg 1 is not set:
  323. message "&fSets the amount of kills or deaths a player has."
  324. message "&f/killsadmin set kills,deaths <player> <amount>"
  325. message "&fAdds to the kills or deaths a player has."
  326. message "&f/killsadmin add kills,deaths <player> <amount>"
  327. message "&fRemoves from the amount of kills or deaths a player has."
  328. message "&f/killsadmin remove kills,deaths <player> <amount>"
  329. stop
  330. if arg 1 and arg 2 and arg 3 and arg 4 is set:
  331. if arg 2 is "kills" or "deaths":
  332. if arg 4 is greater than or equal to 0:
  333. if arg 1 is "set":
  334. if {%arg 2%::%uuid of arg 3%} is not set:
  335. set {Kills::%uuid of arg 3%} to 0
  336. set {Deaths::%uuid of arg 3%} to 0
  337. set {%arg 2%::%uuid of arg 3%} to arg 4
  338. message "&7You set the &c%arg 2% &7value of &b%arg 3% &7to &e%arg 4%&7."
  339. else if arg 1 is "add":
  340. if {%arg 2%::%uuid of arg 3%} is not set:
  341. set {Kills::%uuid of arg 3%} to 0
  342. set {Deaths::%uuid of arg 3%} to 0
  343. add arg 4 to {%arg 2%::%uuid of arg 3%}
  344. message "&7You added &e%arg 4% &7to the &c%arg 2% &7value of &b%arg 3%&7."
  345. else if arg 1 is "remove":
  346. if {%arg 2%::%uuid of arg 3%} is not set:
  347. set {Kills::%uuid of arg 3%} to 0
  348. set {Deaths::%uuid of arg 3%} to 0
  349. remove arg 4 from {%arg 2%::%uuid of arg 3%}
  350. message "&7You removed &e%arg 4% &7from the &c%arg 2% &7value of &b%arg 3%&7."
  351. if {%arg 2%::%uuid of arg 3%} is less than 0:
  352. set {%arg 2%::%uuid of arg 3%} to 0
  353. else:
  354. make player execute command "killsadmin"
  355. else:
  356. message "&cYou must specify an amount above or equal to 0."
  357. else:
  358. message "&cYou must specify either kills or deaths."
  359. else:
  360. make player execute command "killsadmin"
  361.  
  362. # #########################################################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement