Implemented Doubling Money scammer bots at GE

Converted some classes to Kotlin
Fixed a trading bug when you removed an item, the modified slot would flash on the wrong side
This commit is contained in:
Dan Ginovker
2022-12-11 06:45:42 +00:00
committed by Ryan
parent 4193e6131c
commit 97e74320fb
31 changed files with 1390 additions and 935 deletions
@@ -0,0 +1,68 @@
{
"noob": [
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"3","id":"1265"},{"amount":"1","charge":"1000","slot":"5","id":"1171"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"0"},{"color":"0","look":"11"},{"color":"16","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"34"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1169"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"9183"},{"amount":"1","charge":"1000","slot":"4","id":"1131"},{"amount":"1","charge":"1000","slot":"7","id":"2495"},{"amount":"1","charge":"1000","slot":"9","id":"2491"},{"amount":"1","charge":"1000","slot":"10","id":"88"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"106"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1163"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"5698"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"3105"}]},
{"appearance":{"appearance_cache":[{"color":"9","look":"266"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"3","id":"1333"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"11019"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"2910"},{"amount":"1","charge":"1000","slot":"1","id":"10499"},{"amount":"1","charge":"1000","slot":"2","id":"552"},{"amount":"1","charge":"1000","slot":"3","id":"861"},{"amount":"1","charge":"1000","slot":"4","id":"544"},{"amount":"1","charge":"1000","slot":"7","id":"2497"},{"amount":"1","charge":"1000","slot":"9","id":"7458"},{"amount":"1","charge":"1000","slot":"10","id":"2904"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"1007"},{"amount":"1","charge":"1000","slot":"3","id":"1381"},{"amount":"1","charge":"1000","slot":"4","id":"426"},{"amount":"1","charge":"1000","slot":"7","id":"428"}]},
{"appearance":{"appearance_cache":[{"color":"20","look":"267"},{"color":"0","look":"12"},{"color":"0","look":"18"},{"color":"0","look":"31"},{"color":"4","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"3","id":"6908"},{"amount":"1","charge":"1000","slot":"4","id":"1135"},{"amount":"1","charge":"1000","slot":"7","id":"428"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"6","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1161"},{"amount":"1","charge":"1000","slot":"3","id":"1287"},{"amount":"1","charge":"1000","slot":"4","id":"1123"},{"amount":"1","charge":"1000","slot":"5","id":"1199"},{"amount":"1","charge":"1000","slot":"7","id":"1073"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1153"},{"amount":"1","charge":"1000","slot":"3","id":"1363"},{"amount":"1","charge":"1000","slot":"4","id":"6184"},{"amount":"1","charge":"1000","slot":"5","id":"1540"},{"amount":"1","charge":"1000","slot":"7","id":"6185"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11021"},{"amount":"1","charge":"1000","slot":"1","id":"4411"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"1333"},{"amount":"1","charge":"1000","slot":"4","id":"11020"},{"amount":"1","charge":"1000","slot":"5","id":"1185"},{"amount":"1","charge":"1000","slot":"7","id":"11022"},{"amount":"1","charge":"1000","slot":"10","id":"11019"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1949"},{"amount":"1","charge":"1000","slot":"1","id":"1007"},{"amount":"1","charge":"1000","slot":"3","id":"1381"},{"amount":"1","charge":"1000","slot":"4","id":"426"},{"amount":"1","charge":"1000","slot":"5","id":"1540"},{"amount":"1","charge":"1000","slot":"7","id":"428"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10774"},{"amount":"1","charge":"1000","slot":"1","id":"10069"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"1333"},{"amount":"1","charge":"1000","slot":"4","id":"1125"},{"amount":"1","charge":"1000","slot":"7","id":"1077"},{"amount":"1","charge":"1000","slot":"9","id":"2997"},{"amount":"1","charge":"1000","slot":"10","id":"7114"}]}
],
"intermediate": [
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"3","id":"1265"},{"amount":"1","charge":"1000","slot":"5","id":"1171"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"1"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"2637"},{"amount":"1","charge":"1000","slot":"1","id":"6568"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1305"},{"amount":"1","charge":"1000","slot":"4","id":"3140"},{"amount":"1","charge":"1000","slot":"5","id":"6524"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"9","id":"3060"},{"amount":"1","charge":"1000","slot":"10","id":"11732"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"1"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11674"},{"amount":"1","charge":"1000","slot":"1","id":"10720"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"1387"},{"amount":"1","charge":"1000","slot":"4","id":"8839"},{"amount":"1","charge":"1000","slot":"7","id":"8840"},{"amount":"1","charge":"1000","slot":"9","id":"8842"},{"amount":"1","charge":"1000","slot":"10","id":"11732"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"261"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"9805"},{"amount":"1","charge":"1000","slot":"4","id":"10348"},{"amount":"1","charge":"1000","slot":"10","id":"1837"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"261"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10392"},{"amount":"1","charge":"1000","slot":"1","id":"1007"},{"amount":"1","charge":"1000","slot":"2","id":"11113"},{"amount":"1","charge":"1000","slot":"3","id":"1387"},{"amount":"1","charge":"1000","slot":"4","id":"1117"},{"amount":"1","charge":"1000","slot":"5","id":"1173"},{"amount":"1","charge":"1000","slot":"7","id":"1075"},{"amount":"1","charge":"1000","slot":"10","id":"4129"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"3755"},{"amount":"1","charge":"1000","slot":"1","id":"2412"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1383"},{"amount":"1","charge":"1000","slot":"4","id":"4091"},{"amount":"1","charge":"1000","slot":"7","id":"4093"},{"amount":"1","charge":"1000","slot":"9","id":"7462"},{"amount":"1","charge":"1000","slot":"10","id":"10696"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9755"},{"amount":"1","charge":"1000","slot":"1","id":"9754"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1275"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"88"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"106"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11665"},{"amount":"1","charge":"1000","slot":"1","id":"9807"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"13290"},{"amount":"1","charge":"1000","slot":"4","id":"8839"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"8840"},{"amount":"1","charge":"1000","slot":"9","id":"8842"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"106"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9672"},{"amount":"1","charge":"1000","slot":"1","id":"9783"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"9674"},{"amount":"1","charge":"1000","slot":"7","id":"2497"},{"amount":"1","charge":"1000","slot":"9","id":"7458"},{"amount":"1","charge":"1000","slot":"10","id":"3105"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"106"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10828"},{"amount":"1","charge":"1000","slot":"1","id":"9763"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"8850"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"3105"}]},
{"appearance":{"appearance_cache":[{"color":"9","look":"266"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10828"},{"amount":"1","charge":"1000","slot":"1","id":"2414"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"9802"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"6182"},{"amount":"1","charge":"1000","slot":"1","id":"4355"},{"amount":"1","charge":"1000","slot":"2","id":"1478"},{"amount":"1","charge":"1000","slot":"3","id":"9185"},{"amount":"1","charge":"1000","slot":"4","id":"544"},{"amount":"1","charge":"1000","slot":"7","id":"2497"}]} ,
{"appearance":{"appearance_cache":[{"color":"1","look":"1"},{"color":"0","look":"10"},{"color":"14","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"20","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"10071"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"8872"},{"amount":"1","charge":"1000","slot":"9","id":"1059"},{"amount":"1","charge":"1000","slot":"10","id":"88"}]},
{"appearance":{"appearance_cache":[{"color":"20","look":"278"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1149"},{"amount":"1","charge":"1000","slot":"1","id":"6568"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1305"},{"amount":"1","charge":"1000","slot":"4","id":"2623"},{"amount":"1","charge":"1000","slot":"5","id":"6524"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]},
{"appearance":{"appearance_cache":[{"color":"20","look":"1"},{"color":"0","look":"14"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"4413"},{"amount":"1","charge":"1000","slot":"3","id":"1271"},{"amount":"1","charge":"1000","slot":"4","id":"1123"},{"amount":"1","charge":"1000","slot":"7","id":"1073"}]},
{"appearance":{"appearance_cache":[{"color":"20","look":"1"},{"color":"0","look":"14"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"3751"},{"amount":"1","charge":"1000","slot":"1","id":"10499"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"546"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"548"},{"amount":"1","charge":"1000","slot":"10","id":"3105"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"14120"},{"amount":"1","charge":"1000","slot":"2","id":"9470"},{"amount":"1","charge":"1000","slot":"3","id":"1305"},{"amount":"1","charge":"1000","slot":"4","id":"10822"},{"amount":"1","charge":"1000","slot":"5","id":"1540"},{"amount":"1","charge":"1000","slot":"7","id":"10824"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1153"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4153"},{"amount":"1","charge":"1000","slot":"4","id":"1115"},{"amount":"1","charge":"1000","slot":"7","id":"1067"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"3751"},{"amount":"1","charge":"1000","slot":"1","id":"6568"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"5698"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"8847"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"4131"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1163"},{"amount":"1","charge":"1000","slot":"2","id":"3853"},{"amount":"1","charge":"1000","slot":"3","id":"1373"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"1079"}]} ,
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11021"},{"amount":"1","charge":"1000","slot":"2","id":"3853"},{"amount":"1","charge":"1000","slot":"3","id":"1373"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"1079"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11021"},{"amount":"1","charge":"1000","slot":"1","id":"14081"},{"amount":"1","charge":"1000","slot":"2","id":"3853"},{"amount":"1","charge":"1000","slot":"3","id":"1373"},{"amount":"1","charge":"1000","slot":"4","id":"6184"},{"amount":"1","charge":"1000","slot":"7","id":"6185"},{"amount":"1","charge":"1000","slot":"10","id":"3107"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"6","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"6182"},{"amount":"1","charge":"1000","slot":"1","id":"10636"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1371"},{"amount":"1","charge":"1000","slot":"4","id":"10633"},{"amount":"1","charge":"1000","slot":"5","id":"3122"},{"amount":"1","charge":"1000","slot":"7","id":"6181"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"10071"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1381"},{"amount":"1","charge":"1000","slot":"10","id":"88"}]}
],
"veteran": [
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1038"},{"amount":"1","charge":"1000","slot":"1","id":"6570"},{"amount":"1","charge":"1000","slot":"2","id":"10360"},{"amount":"1","charge":"1000","slot":"3","id":"3053"},{"amount":"1","charge":"1000","slot":"4","id":"3140"},{"amount":"1","charge":"1000","slot":"5","id":"1171"},{"amount":"1","charge":"1000","slot":"7","id":"10394"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]},
{"appearance":{"appearance_cache":[{"color":"4","look":"48"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1038"},{"amount":"1","charge":"1000","slot":"1","id":"6570"},{"amount":"1","charge":"1000","slot":"2","id":"10360"},{"amount":"1","charge":"1000","slot":"3","id":"3053"},{"amount":"1","charge":"1000","slot":"4","id":"3140"},{"amount":"1","charge":"1000","slot":"5","id":"1171"},{"amount":"1","charge":"1000","slot":"7","id":"10394"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]},
{"appearance":{"appearance_cache":[{"color":"4","look":"48"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9950"},{"amount":"1","charge":"1000","slot":"1","id":"6570"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"7668"},{"amount":"1","charge":"1000","slot":"4","id":"2503"},{"amount":"1","charge":"1000","slot":"7","id":"2497"},{"amount":"1","charge":"1000","slot":"9","id":"5556"},{"amount":"1","charge":"1000","slot":"10","id":"11732"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"261"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"9805"},{"amount":"1","charge":"1000","slot":"4","id":"10348"},{"amount":"1","charge":"1000","slot":"10","id":"1837"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"9807"},{"amount":"1","charge":"1000","slot":"2","id":"1656"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"9","id":"7462"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9758"},{"amount":"1","charge":"1000","slot":"1","id":"9757"},{"amount":"1","charge":"1000","slot":"2","id":"1656"},{"amount":"1","charge":"1000","slot":"3","id":"1387"},{"amount":"1","charge":"1000","slot":"4","id":"10378"},{"amount":"1","charge":"1000","slot":"5","id":"1183"},{"amount":"1","charge":"1000","slot":"7","id":"10380"},{"amount":"1","charge":"1000","slot":"9","id":"7462"},{"amount":"1","charge":"1000","slot":"10","id":"10696"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10828"},{"amount":"1","charge":"1000","slot":"1","id":"10635"},{"amount":"1","charge":"1000","slot":"2","id":"9470"},{"amount":"1","charge":"1000","slot":"3","id":"9185"},{"amount":"1","charge":"1000","slot":"4","id":"10386"},{"amount":"1","charge":"1000","slot":"5","id":"3842"},{"amount":"1","charge":"1000","slot":"7","id":"10388"},{"amount":"1","charge":"1000","slot":"10","id":"1837"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9755"},{"amount":"1","charge":"1000","slot":"1","id":"9754"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1275"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"88"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9764"},{"amount":"1","charge":"1000","slot":"1","id":"9763"},{"amount":"1","charge":"1000","slot":"2","id":"1704"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"108"},{"color":"3","look":"34"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9814"},{"amount":"1","charge":"1000","slot":"1","id":"10662"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"108"},{"color":"3","look":"34"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9749"},{"amount":"1","charge":"1000","slot":"1","id":"10662"},{"amount":"1","charge":"1000","slot":"2","id":"6585"},{"amount":"1","charge":"1000","slot":"3","id":"5016"},{"amount":"1","charge":"1000","slot":"4","id":"13858"},{"amount":"1","charge":"1000","slot":"5","id":"7053"},{"amount":"1","charge":"1000","slot":"7","id":"13861"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11718"},{"amount":"1","charge":"1000","slot":"1","id":"10499"},{"amount":"1","charge":"1000","slot":"2","id":"87"},{"amount":"1","charge":"1000","slot":"3","id":"9185"},{"amount":"1","charge":"1000","slot":"4","id":"11720"},{"amount":"1","charge":"1000","slot":"5","id":"11283"},{"amount":"1","charge":"1000","slot":"7","id":"11722"},{"amount":"1","charge":"1000","slot":"9","id":"7458"},{"amount":"1","charge":"1000","slot":"10","id":"6920"}]},
{"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"6918"},{"amount":"1","charge":"1000","slot":"1","id":"9771"},{"amount":"1","charge":"1000","slot":"2","id":"87"},{"amount":"1","charge":"1000","slot":"3","id":"1387"},{"amount":"1","charge":"1000","slot":"4","id":"6916"},{"amount":"1","charge":"1000","slot":"5","id":"11283"},{"amount":"1","charge":"1000","slot":"7","id":"6924"},{"amount":"1","charge":"1000","slot":"9","id":"6922"},{"amount":"1","charge":"1000","slot":"10","id":"6920"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"45"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"6","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"2637"},{"amount":"1","charge":"1000","slot":"1","id":"9769"},{"amount":"1","charge":"1000","slot":"2","id":"1478"},{"amount":"1","charge":"1000","slot":"3","id":"4151"},{"amount":"1","charge":"1000","slot":"4","id":"10460"},{"amount":"1","charge":"1000","slot":"5","id":"3842"},{"amount":"1","charge":"1000","slot":"7","id":"10394"},{"amount":"1","charge":"1000","slot":"9","id":"2912"},{"amount":"1","charge":"1000","slot":"10","id":"2904"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"45"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"6","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"8903"},{"amount":"1","charge":"1000","slot":"1","id":"9807"},{"amount":"1","charge":"1000","slot":"2","id":"6585"},{"amount":"1","charge":"1000","slot":"3","id":"4151"},{"amount":"1","charge":"1000","slot":"4","id":"14479"},{"amount":"1","charge":"1000","slot":"5","id":"1187"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"9","id":"2912"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]},
{"appearance":{"appearance_cache":[{"color":"20","look":"278"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"10635"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4151"},{"amount":"1","charge":"1000","slot":"4","id":"4757"},{"amount":"1","charge":"1000","slot":"5","id":"7053"},{"amount":"1","charge":"1000","slot":"7","id":"4759"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]},
{"appearance":{"appearance_cache":[{"color":"20","look":"278"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1163"},{"amount":"1","charge":"1000","slot":"1","id":"9766"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"10551"},{"amount":"1","charge":"1000","slot":"5","id":"8850"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"9","id":"7455"}]},
{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"2643"},{"amount":"1","charge":"1000","slot":"1","id":"10446"},{"amount":"1","charge":"1000","slot":"2","id":"6585"},{"amount":"1","charge":"1000","slot":"3","id":"4151"},{"amount":"1","charge":"1000","slot":"4","id":"4712"},{"amount":"1","charge":"1000","slot":"5","id":"8850"},{"amount":"1","charge":"1000","slot":"7","id":"4714"},{"amount":"1","charge":"1000","slot":"9","id":"7461"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]},
{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"6","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10828"},{"amount":"1","charge":"1000","slot":"1","id":"2414"},{"amount":"1","charge":"1000","slot":"2","id":"6585"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"10551"},{"amount":"1","charge":"1000","slot":"5","id":"1187"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"9","id":"7462"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]}
]
}
@@ -392,7 +392,7 @@ public final class TzhaarFightPitsPlugin extends ActivityPlugin {
}
}
}
int skill = lastVictor.getSkills().getHighestCombatSkill();
int skill = lastVictor.getSkills().getHighestCombatSkillId();
switch (skill) {
case Skills.ATTACK:
case Skills.STRENGTH:
@@ -0,0 +1,29 @@
package core.game.interaction.player
import core.game.interaction.Option._P_ASSIST
import core.game.interaction.Option._P_TRADE
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.request.RequestType
import core.plugin.Initializable
import rs09.game.interaction.IntType
import rs09.game.interaction.InteractionListener
/**
* Represents the plugin used to handle the player option interacting.
* @author 'Vexia
* @author dginovker
* @version 2.0
*/
@Initializable
class RequestOption : InteractionListener {
override fun defineListeners() {
on(_P_TRADE.name, IntType.PLAYER) { player, node ->
player.requestManager.request((node as Player), RequestType.TRADE)
return@on true
}
on(_P_ASSIST.name, IntType.PLAYER) { player, node ->
player.requestManager.request((node as Player), RequestType.ASSIST)
return@on true
}
}
}
@@ -1,30 +0,0 @@
package core.game.interaction.player;
import core.game.interaction.Option;
import core.game.interaction.OptionHandler;
import core.game.node.Node;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.request.RequestType;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Represents the plugin used to handle the player option interacting.
* @author 'Vexia
*/
@Initializable
public final class RequestOptionPlugin extends OptionHandler {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
Option._P_ASSIST.setHandler(this);
Option._P_TRADE.setHandler(this);
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
player.getRequestManager().request((Player) node, RequestType.forOption(option));
return true;
}
}
@@ -1,132 +0,0 @@
package core.game.node.entity.player.link.request;
import core.game.node.entity.player.Player;
import rs09.game.world.GameWorld;
/**
* Represents a managing class for requests of a player.
* @author Vexia
*/
public final class RequestManager {
/**
* Represents the player instance.
*/
private final Player player;
/**
* Represents the target being requested.
*/
private Player target;
/**
* Constructs a new {@code RequestManager} {@code Object}.
* @param player the player.
*/
public RequestManager(final Player player) {
this.player = player;
}
/**
* Method used to send a request type to a target.
* @param target the target.
* @param type the type of request.
* @return {@code True} if successful in requesting.
*/
public boolean request(final Player target, final RequestType type) {
if (!canRequest(type, target)) {
return false;
}
if (acceptExisting(target, type)) {
return true;
}
player.getPacketDispatch().sendMessage(type.getMessage());
target.getPacketDispatch().sendMessage(type.getRequestMessage(player));
player.setAttribute("lastRequest", type);
this.target = target;
return true;
}
/**
* Method used to check if a player can continue with a request.
* @param type the type.
* @param target the target.
* @return {@code True} if they can request.
*/
private boolean canRequest(RequestType type, Player target) {
if (target == player) {
return false;
}
if (!target.getLocation().withinDistance(player.getLocation(), 15)) {
player.getPacketDispatch().sendMessage("Unable to find " + target.getUsername() + ".");
return false;
}
if (!target.isActive() || target.getInterfaceManager().isOpened()) {
player.getPacketDispatch().sendMessage("Other player is busy at the moment.");
return false;
}
if (target.getAttribute("busy", 0) > GameWorld.getTicks() || player.getAttribute("busy", 0) > GameWorld.getTicks()) {
player.getPacketDispatch().sendMessage("Other player is busy at the moment.");
return false;
}
if (!player.getZoneMonitor().canRequest(type, target)) {
return false;
}
return type.canRequest(player, target);
}
/**
* Method used to check if we can accept an existing request.
* @param target the target.
* @param type the type.
* @return {@code True} if so.
*/
public boolean acceptExisting(final Player target, final RequestType type) {
final RequestType lastType = target.getAttribute("lastRequest", null);
if (lastType == type && player == target.getRequestManager().getTarget()) {
close(player);
clear();
target.getRequestManager().clear();
player.setAttribute("busy", GameWorld.getTicks() + 2);
target.setAttribute("busy", GameWorld.getTicks() + 2);
type.getModule().open(player, target);
return true;
}
close(player);
return false;
}
/**
* Closes the components for the player.
* @param player the player.
*/
private void close(Player player) {
player.getDialogueInterpreter().close();
player.getInterfaceManager().close();
player.getInterfaceManager().closeChatbox();
}
/**
* Method used to clear the cached target.
*/
public void clear() {
this.target = null;
}
/**
* Gets the player.
* @return the player.
*/
public Player getPlayer() {
return player;
}
/**
* Gets the target.
* @return the target.
*/
public Player getTarget() {
return target;
}
}
@@ -0,0 +1,113 @@
package core.game.node.entity.player.link.request
import core.game.node.entity.player.Player
import rs09.game.ai.AIRepository
import rs09.game.ai.general.scriptrepository.DoublingMoney
import rs09.game.world.GameWorld.ticks
/**
* Represents a managing class for requests of a player.
* @author Vexia
* @author dginovker
* @version 2.0
*/
class RequestManager(val player: Player) {
/**
* Represents the target being requested.
*/
var target: Player? = null
private set
/**
* Method used to send a request type to a target.
* @param target the target.
* @param type the type of request.
* @return `True` if successful.
*/
fun request(target: Player, type: RequestType): Boolean {
if (!canRequest(type, target)) {
return false
}
if (acceptExisting(target, type)) {
return true
}
player.packetDispatch.sendMessage(type.message)
target.packetDispatch.sendMessage(type.getRequestMessage(player))
player.setAttribute("lastRequest", type)
this.target = target
// If the target is a bot, get their bot manager to handle the request.
if (target.isArtificial) {
val bot = AIRepository.PulseRepository[target.username.lowercase()]
if (bot != null && bot.botScript is DoublingMoney) {
bot.botScript.tradeReceived(player)
}
}
return true
}
/**
* Method used to check if a player can continue with a request.
* @param type the type.
* @param target the target.
* @return `True` if so.
*/
private fun canRequest(type: RequestType, target: Player): Boolean {
if (target === player) {
return false
}
if (!target.location.withinDistance(player.location, 15)) {
player.packetDispatch.sendMessage("Unable to find " + target.username + ".")
return false
}
if (!target.isActive || target.interfaceManager.isOpened) {
player.packetDispatch.sendMessage("Other player is busy at the moment.")
return false
}
if (target.getAttribute("busy", 0) > ticks || player.getAttribute("busy", 0) > ticks) {
player.packetDispatch.sendMessage("Other player is busy at the moment.")
return false
}
return if (!player.zoneMonitor.canRequest(type, target)) {
false
} else type.canRequest(player, target)
}
/**
* Method used to check if we can accept an existing request.
* @param target the target.
* @param type the type.
* @return `True` if so.
*/
private fun acceptExisting(target: Player, type: RequestType): Boolean {
val lastType = target.getAttribute<RequestType>("lastRequest", null)
if (lastType === type && player === target.requestManager.target) {
close(player)
clear()
target.requestManager.clear()
player.setAttribute("busy", ticks + 2)
target.setAttribute("busy", ticks + 2)
type.module.open(player, target)
return true
}
close(player)
return false
}
/**
* Closes the components for the player.
* @param player the player.
*/
private fun close(player: Player) {
player.dialogueInterpreter.close()
player.interfaceManager.close()
player.interfaceManager.closeChatbox()
}
/**
* Method used to clear the cached target.
*/
fun clear() {
target = null
}
}
@@ -1,18 +0,0 @@
package core.game.node.entity.player.link.request;
import core.game.node.entity.player.Player;
/**
* Represents the module used for all request types.
* @author 'Vexia
*/
public interface RequestModule {
/**
* Method invoked when the targeting player accepts a request.
* @param player the player.
* @param target the target.
*/
public void open(final Player player, final Player target);
}
@@ -0,0 +1,18 @@
package core.game.node.entity.player.link.request
import core.game.node.entity.player.Player
/**
* Represents the module used for all request types.
* @author 'Vexia
* @author dginovker
* @version 2.0
*/
interface RequestModule {
/**
* Method invoked when the targeting player accepts a request.
* @param player the player.
* @param target the target.
*/
fun open(player: Player?, target: Player?)
}
@@ -1,101 +0,0 @@
package core.game.node.entity.player.link.request;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.request.assist.AssistSession;
import core.game.node.entity.player.link.request.trade.TradeModule;
/**
* Represents a request type.
* @author 'Vexia
* @author Emperor
*/
public class RequestType {
/**
* The trade request type.
*/
public static final RequestType TRADE = new RequestType("Sending a trade offer...", ":tradereq:", new TradeModule());
/**
* The assist request type.
*/
public static final RequestType ASSIST = new RequestType("Sending assistance request...", ":assistreq:", new AssistSession());
/**
* Represents the message to send for the player when requesting.
*/
private final String message;
/**
* Represents the requesting message type.
*/
private final String requestMessage;
/**
* Represents the module used for this type of requesting.
*/
private final RequestModule module;
/**
* Constructs a new {@code RequestManager {@code Object}.
* @param message the message.
* @param requestMessage the requesting message.
*/
public RequestType(String message, String requestMessage, RequestModule module) {
this.message = message;
this.requestMessage = requestMessage;
this.module = module;
}
/**
* Checks if the request can be made.
* @param player The player.
* @param target The target.
* @return {@code True} if so.
*/
public boolean canRequest(Player player, Player target) {
return true;
}
/**
* Gets the requesting message formated with the targets name.
* @param target the target.
* @return the message to send.
*/
public String getRequestMessage(Player target) {
return target.getUsername() + getRequestMessage();
}
/**
* Method used to get the request type by the option being handled.
* @param option the option being handled.
* @return the request type in correlation.
*/
public static RequestType forOption(String option) {
return option.equals("trade with") ? TRADE : ASSIST;
}
/**
* Gets the message.
* @return The message.
*/
public String getMessage() {
return message;
}
/**
* Gets the requestMessage.
* @return The requestMessage.
*/
public String getRequestMessage() {
return requestMessage;
}
/**
* Gets the request module.
* @return the module.
*/
public RequestModule getModule() {
return module;
}
}
@@ -0,0 +1,63 @@
package core.game.node.entity.player.link.request
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.request.assist.AssistSession
import core.game.node.entity.player.link.request.trade.TradeModule
/**
* Represents a request type.
* @author 'Vexia
* @author Emperor
* @author dginovker
* @version 2.0
*/
open class RequestType
/**
* Constructs a new `RequestManager { Object}.
* message the message.
* requestMessage the requesting message.`
*/(
/**
* Represents the message to send for the player when requesting.
*/
val message: String,
/**
* Represents the requesting message type.
*/
val requestMessage: String,
/**
* Represents the module used for this type of requesting.
*/
val module: RequestModule
) {
/**
* Checks if the request can be made.
* @param player The player.
* @param target The target.
* @return `True` if so.
*/
open fun canRequest(player: Player?, target: Player?): Boolean {
return true
}
/**
* Gets the requesting message formated with the targets name.
* @param target the target.
* @return the message to send.
*/
fun getRequestMessage(target: Player): String {
return target.username + requestMessage
}
companion object {
/**
* The trade request type.
*/
val TRADE = RequestType("Sending a trade offer...", ":tradereq:", TradeModule(null, null))
/**
* The assist request type.
*/
val ASSIST = RequestType("Sending assistance request...", ":assistreq:", AssistSession())
}
}
@@ -1,546 +0,0 @@
package core.game.node.entity.player.link.request.trade;
import core.game.component.Component;
import core.game.container.Container;
import core.game.container.ContainerType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.request.RequestModule;
import core.game.node.item.GroundItemManager;
import core.game.node.item.Item;
import core.game.system.monitor.PlayerMonitor;
import rs09.game.system.SystemLogger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Represents the module use to handle a request between trading of two players.
* @author Vexia
*
*/
public final class TradeModule implements RequestModule {
/**
* Represents the overlay interface component.
*/
public static final Component OVERLAY_INTERFACE = new Component(336);
/**
* Represents the main interface component.
*/
public static final Component MAIN_INTERFACE = new Component(335).setCloseEvent(new TradeCloseEvent());
/**
* Represents the accept interface component.
*/
public static final Component ACCEPT_INTERFACE = new Component(334).setCloseEvent(new TradeCloseEvent());
/**
* The inventory params for the runscript.
*/
public static final Object[] INVENTORY_PARAMS = new Object[] { "", "", "", "Lend", "Offer-X", "Offer-All", "Offer-10", "Offer-5", "Offer", -1, 0, 7, 4, 93, (336 << 16) };
/**
* The trade params for the run script.
*/
public static final Object[] TRADE_PARAMS = new Object[] { "", "", "", "", "Remove-X", "Remove-All", "Remove-10", "Remove-5", "Remove", -1, 0, 7, 4, 90, (335 << 16) | 30 };
/**
* The partener params for the run script.
*/
public static final Object[] PARTENER_PARAMS = new Object[] { "", "", "", "", "", "", "", "", "", -1, 0, 7, 4, 91, (335 << 16) | 32 };
/**
* Represents the childs that should be hidden.
*/
public static final int[] HIDDEN_CHILDS = new int[] { 42, 43, 44, 42, 44, 40, 41 };
/**
* If the container has been retained.
*/
private boolean retained;
/**
* Represents the player instance.
*/
private Player player;
/**
* Represents the target instance.
*/
private Player target;
/**
* Represents the container of this session.
*/
private TradeContainer container;
/**
* Represents if this session has accepted.
*/
private boolean accepted;
/**
* Represents if the trade is modified.
*/
private boolean modified = false;
/**
* Represents the stage of the trade(0=started, 1=second accept)
*/
private int stage;
/**
* Constructs a new {@code TradeModule} {@code Object}.
* @param player the player.
* @param target the target.
*/
public TradeModule(final Player player, final Player target) {
this.player = player;
this.target = target;
this.container = new TradeContainer(player);
}
/**
* Constructs a new {@code TradeModule} {@code Object}.
*/
public TradeModule() {
/**
* empty.
*/
}
@Override
public void open(Player player, Player target) {
extend(player, target);
if (getExtension(target) == null || getExtension(player) == null) {
return;
}
getExtension(player).openInterface(getInterface(stage)).display(stage);
if (getExtension(target) == null || getExtension(player) == null) {
return;
}
getExtension(target).openInterface(getInterface(stage)).display(stage);
player.getDialogueInterpreter().close();
target.getDialogueInterpreter().close();
}
/**
* Method used to update the trade interfaces.
*/
public void update() {
display(stage);
getExtension(target).display(stage);
}
/**
* Method used to extend the module for each participant.
* @param player the player.
* @param target the target.
*/
public static void extend(final Player player, final Player target) {
player.addExtension(TradeModule.class, new TradeModule(player, target));
target.addExtension(TradeModule.class, new TradeModule(target, player));
}
/**
* Method used to get the extension from the player.
* @param player the player.
* @return the module instance.
*/
public static TradeModule getExtension(final Player player) {
return player.getExtension(TradeModule.class);
}
/**
* Method used to open an interface at a stage.
* @param component the component.
* @return the module instance for chaining.
*/
private TradeModule openInterface(final Component component) {
return component == MAIN_INTERFACE ? openMain() : openSecond();
}
/**
* Gets the accepting message to display.
* @return the message.
*/
private String getAcceptMessage() {
boolean otherAccept = TradeModule.getExtension(target).isAccepted();
return !otherAccept && !accepted ? "" : otherAccept ? "Other player has accepted." : "Waiting for other player...";
}
/**
* Method used to display the interface display depending on stage.
* @param stage the stage.
* @return module the module instance for chaining.
*/
private TradeModule display(int stage) {
switch (stage) {
case 0:
for (int i : HIDDEN_CHILDS) {
player.getPacketDispatch().sendString("", MAIN_INTERFACE.getId(), i);
}
player.getPacketDispatch().sendString("Trading With: " + target.getUsername(), 335, 15);
player.getPacketDispatch().sendString(target.getUsername() + " has " + (target.getInventory().freeSlots() == 0 ? "no" : (target.getInventory().freeSlots())) + " free inventory slots.", 335, 21);
player.getPacketDispatch().sendString(getAcceptMessage(), 335, 36);
break;
case 1:
player.getPacketDispatch().sendString("<col=00FFFF>Trading with:<br>" + "<col=00FFFF>" + target.getUsername().substring(0, 1).toUpperCase() + target.getUsername().substring(1), 334, 2);
final String acceptMessage = getAcceptMessage();
if (acceptMessage != "") {
player.getPacketDispatch().sendString(acceptMessage, 334, 33);
}
player.getInterfaceManager().restoreTabs();
break;
}
displayModified(stage);
container.update(true);
return this;
}
/**
* Gets the interface for the current stage.
* @param stage the stage.
* @return the component.
*/
private Component getInterface(int stage) {
return stage == 0 ? MAIN_INTERFACE : ACCEPT_INTERFACE;
}
/**
* Method used to display if the trade is modified.
* @param stage the sytage.
*/
private void displayModified(int stage) {
final boolean otherModified = TradeModule.getExtension(target).isModified();
if (stage == 1) {
player.getPacketDispatch().sendInterfaceConfig(334, 45, !modified);
player.getPacketDispatch().sendInterfaceConfig(334, 46, !otherModified);
} else {
if (otherModified) {
player.getConfigManager().set(1043, 1);
}
if (modified) {
player.getConfigManager().set(1042, 1);
}
}
}
/**
* Method used to decline this offer.
*/
public void decline() {
player.getInterfaceManager().close();
target.getPacketDispatch().sendMessage("<col=FF0000>Other player has declined trade!</col>");
}
/**
* Method used to check if the next stage can proceed.
*/
private void nextStage() {
if (accepted && TradeModule.getExtension(target).isAccepted()) {
if (stage == 0) {
if (!hasSpace()) {
return;
}
incrementStage();
openInterface(getInterface(stage));
TradeModule.getExtension(target).incrementStage();
TradeModule.getExtension(target).openInterface(getInterface(stage));
TradeModule.getExtension(target).setAccepted(false, false);
setAccepted(false, false);
} else {
giveContainers(this);
incrementStage();
TradeModule.getExtension(target).incrementStage();
TradeModule.getExtension(target).setAccepted(false, false);
setAccepted(false, false);
player.getInterfaceManager().close();
return;
}
}
update();
}
/**
* Method used to open the main interface.
* @return the module instance for chaining.
*/
private TradeModule openMain() {
player.getInterfaceManager().closeDefaultTabs();
player.getInterfaceManager().open(MAIN_INTERFACE);
player.getInterfaceManager().openSingleTab(OVERLAY_INTERFACE);
player.getInventory().refresh();
player.getPacketDispatch().sendIfaceSettings(1278, 30, 335, 0, 27);
player.getPacketDispatch().sendIfaceSettings(1026, 32, 335, 0, 27);
player.getPacketDispatch().sendIfaceSettings(1278, 0, 336, 0, 27);
player.getPacketDispatch().sendIfaceSettings(2360446, 0, 335, 0, 27);
player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", INVENTORY_PARAMS);
player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", TRADE_PARAMS);
player.getPacketDispatch().sendRunScript(695, "IviiiIsssssssss", PARTENER_PARAMS);
return this;
}
/**
* Method used to open the second interface.
* @return the module instance for chaining.
*/
private TradeModule openSecond() {
player.getInterfaceManager().open(ACCEPT_INTERFACE);
player.getInterfaceManager().closeSingleTab();
displayOffer(container, 37);
displayOffer(TradeModule.getExtension(target).getContainer(), 41);
return this;
}
/**
* Method used to set the value of accepted.
* @param accept the accept.
*/
public void setAccepted(final boolean accept, boolean update) {
this.accepted = accept;
if (update) {
nextStage();
}
}
/**
* Method used to alert the player the trade has been modified.
* @param slot the slot.
*/
public void alert(final int slot) {
player.getPacketDispatch().sendRunScript(143, "Iiii", new Object[] { slot, 7, 4, 21954593 });
target.getPacketDispatch().sendRunScript(143, "Iiii", new Object[] { slot, 7, 4, 21954594 });
}
/**
* Method used to display an offer.
* @param container the container.
*/
private void displayOffer(final Container container, int child) {
boolean split = container.itemCount() > 14;
if (split) {
player.getPacketDispatch().sendInterfaceConfig(334, child + 1, false);
player.getPacketDispatch().sendInterfaceConfig(334, child + 2, false);
String[] messages = new String[] { getDisplayMessage(splitList(container.toArray(), 0, 14)), getDisplayMessage(splitList(container.toArray(), 14, container.toArray().length)) };
player.getPacketDispatch().sendString(messages[0], 334, child + 1);
player.getPacketDispatch().sendString(messages[1], 334, child + 2);
} else {
player.getPacketDispatch().sendInterfaceConfig(334, child, false);
player.getPacketDispatch().sendString(getDisplayMessage(container.toArray()), 334, child);
}
}
/**
* Method used to get the display message.
* @param items the items.
* @return the message.
*/
private String getDisplayMessage(Item[] items) {
String message = "Absolutely nothing!";
if (items.length > 0) {
message = "";
for (int i = 0; i < items.length; i++) {
if (items[i] == null) {
continue;
}
message = message + "<col=FF9040>" + items[i].getName();
if (items[i].getAmount() > 1) {
message = message + "<col=FFFFFF> x ";
message = message + "<col=FFFF00>" + getFormattedNumber(items[i].getAmount()) + "<br>";
} else {
message = message + "<br>";
}
}
}
return message;
}
/**
* Method used to check if the players & targets have enough space.
* @return {@code True} if so.
*/
private boolean hasSpace() {
boolean hasSpace = true;
if (!player.getInventory().hasSpaceFor(TradeModule.getExtension(target).getContainer())) {
target.getPacketDispatch().sendMessage("Other player doesn't have enough space in their inventory for this trade.");
player.getPacketDispatch().sendMessage("You don't have enough inventory space for this.");
hasSpace = false;
} else if (!target.getInventory().hasSpaceFor(container)) {
player.getPacketDispatch().sendMessage("Other player doesn't have enough space in their inventory for this trade.");
target.getPacketDispatch().sendMessage("You don't have enough inventory space for this.");
hasSpace = false;
}
if (!hasSpace) {
setAccepted(false, true);
TradeModule.getExtension(target).setAccepted(false, true);
}
return hasSpace;
}
/**
* Gets the formatted number.
* @param amount the amount.
* @return the formatted number.
*/
private String getFormattedNumber(int amount) {
return new DecimalFormat("#,###,##0").format(amount).toString();
}
/**
* Method used to give the containers to each participants.
* @param module the module.
*/
private void giveContainers(final TradeModule module) {
final Container pContainer = module.getContainer();
final Container oContainer = TradeModule.getExtension(module.getTarget()).getContainer();
SystemLogger.logTrade(module.getPlayer().getUsername() + " -> " + module.getTarget().getUsername() + " " + Arrays.toString(pContainer.toArray()));
SystemLogger.logTrade(module.getTarget().getUsername() + " -> " + module.getPlayer().getUsername() + " " + Arrays.toString(oContainer.toArray()));
addContainer(module.getPlayer(), module.getTarget(), oContainer);
addContainer(module.getTarget(), module.getPlayer(), pContainer);
module.getTarget().getPacketDispatch().sendMessage("Accepted trade.");
module.getPlayer().getPacketDispatch().sendMessage("Accepted trade.");
}
/**
* Method used to add a container for a player.
* @param player the player.
* @param target the target.
* @param container the container.
*/
private void addContainer(final Player player, Player target, final Container container) {
Container c = new Container(container.itemCount(), ContainerType.ALWAYS_STACK);
c.addAll(container);
String log = "traded => " + target.getName() + " received => {";
for (Item i : container.toArray()) {
if (i == null) {
continue;
}
if (i.getAmount() > player.getInventory().getMaximumAdd(i)) {
i.setAmount(player.getInventory().getMaximumAdd(i));
}
if (!player.getInventory().add(i)) {
GroundItemManager.create(i, player);
}
}
for (Item i : c.toArray()) {
if (i == null) {
continue;
}
log += i.getName() + " x " + i.getAmount() + ",";
}
if (log.charAt(log.length() - 1) == ',') {
log = log.substring(0, log.length() - 1);
}
log += "}";
player.getMonitor().log(log, PlayerMonitor.TRADE_LOG);
}
/**
* Gets the split list as an array.
* @param items the items.
* @param min the min.
* @param max the max.
* @return the split item array.
*/
private Item[] splitList(Item[] items, int min, int max) {
List<Item> list = new ArrayList<>(20);
for (int i = min; i < max; i++) {
if (items[i] == null) {
continue;
}
list.add(items[i]);
}
Item[] array = new Item[list.size()];
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == null) {
continue;
}
array[i] = list.get(i);
}
return array;
}
/**
* Method used to increment the stage.
*/
public void incrementStage() {
stage++;
}
/**
* Gets the stage.
* @return the stage.
*/
public int getStage() {
return stage;
}
/**
* Gets the accepted.
* @return The accepted.
*/
public boolean isAccepted() {
return accepted;
}
/**
* Gets the trade container.
* @return the container.
*/
public TradeContainer getContainer() {
return container;
}
/**
* Gets the player.
* @return The player.
*/
public Player getPlayer() {
return player;
}
/**
* Gets the target.
* @return The target.
*/
public Player getTarget() {
return target;
}
/**
* Gets the modified.
* @return The modified.
*/
public boolean isModified() {
return modified;
}
/**
* Sets the modified.
* @param modified The modified to set.
*/
public void setModified(boolean modified) {
this.modified = modified;
}
/**
* Gets the retained.
* @return The retained.
*/
public boolean isRetained() {
return retained;
}
/**
* Sets the retained.
* @param retained The retained to set.
*/
public void setRetained(boolean retained) {
this.retained = retained;
}
}
@@ -0,0 +1,528 @@
package core.game.node.entity.player.link.request.trade
import core.game.component.Component
import core.game.container.Container
import core.game.container.ContainerType
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.request.RequestModule
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.system.monitor.PlayerMonitor
import rs09.game.ai.AIRepository
import rs09.game.ai.general.scriptrepository.DoublingMoney
import rs09.game.system.SystemLogger
import java.text.DecimalFormat
import java.util.*
/**
* Represents the module use to handle a request between trading of two players.
* @author Vexia
* @author dginovker
* @version 2.0
*/
class TradeModule
/**
* Constructs a new `TradeModule` `Object`.
* @param player the player.
* @param target the target.
*/(player: Player?, target: Player?) : RequestModule {
/**
* If the container has been retained.
*/
var isRetained = false
/**
* Represents the player instance.
*/
var player: Player? = player
private set
/**
* Represents the target instance.
*/
var target: Player? = target
private set
/**
* Represents the container of this session.
*/
var container: TradeContainer? = null
private set
/**
* Represents if this session has accepted.
*/
var isAccepted = false
private set
/**
* Represents if the trade is modified.
*/
var isModified = false
/**
* Represents the stage of the trade(0=started, 1=second accept)
*/
var stage = 0
private set
override fun open(player: Player?, target: Player?) {
extend(player, target)
if (getExtension(target) == null || getExtension(player) == null) {
return
}
getExtension(player)!!.openInterface(getInterface(stage)).display(stage)
if (getExtension(target) == null || getExtension(player) == null) {
return
}
getExtension(target)!!.openInterface(getInterface(stage)).display(stage)
player!!.dialogueInterpreter.close()
target!!.dialogueInterpreter.close()
}
/**
* Method used to update the trade interfaces.
*/
fun update() {
display(stage)
getExtension(target)!!.display(stage)
}
/**
* Method used to open an interface at a stage.
* @param component the component.
* @return the module instance for chaining.
*/
private fun openInterface(component: Component): TradeModule {
return if (component === MAIN_INTERFACE) openMain() else openSecond()
}
/**
* Gets the accepting message to display.
* @return the message.
*/
private val acceptMessage: String
get() {
val otherAccept = getExtension(target)!!.isAccepted
return if (!otherAccept && !isAccepted) "" else if (otherAccept) "Other player has accepted." else "Waiting for other player..."
}
/**
* Method used to display the interface display depending on stage.
* @param stage the stage.
* @return module the module instance for chaining.
*/
private fun display(stage: Int): TradeModule {
when (stage) {
0 -> {
for (i in HIDDEN_CHILDS) {
player!!.packetDispatch.sendString("", MAIN_INTERFACE.id, i)
}
player!!.packetDispatch.sendString("Trading With: " + target!!.username, 335, 15)
player!!.packetDispatch.sendString(
target!!.username + " has " + (if (target!!.inventory.freeSlots() == 0) "no" else target!!.inventory.freeSlots()) + " free inventory slots.",
335,
21
)
player!!.packetDispatch.sendString(acceptMessage, 335, 36)
}
1 -> {
player!!.packetDispatch.sendString(
"<col=00FFFF>Trading with:<br>" + "<col=00FFFF>" + target!!.username.substring(
0,
1
).uppercase(Locale.getDefault()) + target!!.username.substring(1), 334, 2
)
val acceptMessage = acceptMessage
if (acceptMessage !== "") {
player!!.packetDispatch.sendString(acceptMessage, 334, 33)
}
player!!.interfaceManager.restoreTabs()
}
}
displayModified(stage)
container!!.update(true)
return this
}
/**
* Gets the interface for the current stage.
* @param stage the stage, defaults to this TradeModule's stage.
* @return the component.
*/
fun getInterface(stage: Int = this.stage): Component {
return if (stage == 0) MAIN_INTERFACE else ACCEPT_INTERFACE
}
/**
* Gets the interface for the TradeModule stage
* @return the component
*/
fun getInterface(): Component {
return getInterface(stage)
}
/**
* Method used to display red text at the top of the trade window when the trade has been modified
* (Red text appears at the bottom in second trade screen)
* @param stage the sytage.
*/
private fun displayModified(stage: Int) {
val otherModified = getExtension(target)!!.isModified
if (stage == 0) {
// Main interface
if (otherModified) {
player!!.configManager[1043] = 1
}
if (isModified) {
player!!.configManager[1042] = 1
}
} else {
// Accept interface
player!!.packetDispatch.sendInterfaceConfig(334, 45, !isModified)
player!!.packetDispatch.sendInterfaceConfig(334, 46, !otherModified)
}
}
/**
* Method used to display flashing alert if the trade has been modified.
* @param slot the slot.
*/
fun alert(slot: Int) {
player!!.packetDispatch.sendRunScript(143, "Iiii", *arrayOf<Any>(slot, 7, 4, 21954594))
target!!.packetDispatch.sendRunScript(143, "Iiii", *arrayOf<Any>(slot, 7, 4, 21954593))
}
/**
* Method used to decline this offer.
*/
fun decline() {
player!!.interfaceManager.close()
target!!.packetDispatch.sendMessage("<col=FF0000>Other player has declined trade!</col>")
}
/**
* Method used to check if the next stage can proceed.
*/
private fun nextStage() {
if (isAccepted && getExtension(target)!!.isAccepted) {
if (stage == 0) {
if (!hasSpace()) {
return
}
incrementStage()
openInterface(getInterface(stage))
getExtension(target)!!.incrementStage()
getExtension(target)!!.openInterface(getInterface(stage))
getExtension(target)!!.setAccepted(false, false)
setAccepted(false, false)
} else {
giveContainers(this)
incrementStage()
getExtension(target)!!.incrementStage()
getExtension(target)!!.setAccepted(false, false)
setAccepted(false, false)
player!!.interfaceManager.close()
return
}
}
update()
}
/**
* Method used to open the main interface.
* @return the module instance for chaining.
*/
private fun openMain(): TradeModule {
player!!.interfaceManager.closeDefaultTabs()
player!!.interfaceManager.open(MAIN_INTERFACE)
player!!.interfaceManager.openSingleTab(OVERLAY_INTERFACE)
player!!.inventory.refresh()
player!!.packetDispatch.sendIfaceSettings(1278, 30, 335, 0, 27)
player!!.packetDispatch.sendIfaceSettings(1026, 32, 335, 0, 27)
player!!.packetDispatch.sendIfaceSettings(1278, 0, 336, 0, 27)
player!!.packetDispatch.sendIfaceSettings(2360446, 0, 335, 0, 27)
player!!.packetDispatch.sendRunScript(150, "IviiiIsssssssss", *INVENTORY_PARAMS)
player!!.packetDispatch.sendRunScript(150, "IviiiIsssssssss", *TRADE_PARAMS)
player!!.packetDispatch.sendRunScript(695, "IviiiIsssssssss", *PARTENER_PARAMS)
return this
}
/**
* Method used to open the second interface.
* @return the module instance for chaining.
*/
private fun openSecond(): TradeModule {
player!!.interfaceManager.open(ACCEPT_INTERFACE)
player!!.interfaceManager.closeSingleTab()
displayOffer(container, 37)
displayOffer(getExtension(target)!!.container, 41)
return this
}
/**
* Method used to set the value of accepted.
* @param accept whether the trade was accepted or declined
*/
fun setAccepted(accept: Boolean, update: Boolean) {
isAccepted = accept
if (update) {
nextStage()
}
}
/**
* Method used to display an offer.
* @param container the container.
*/
private fun displayOffer(container: Container?, child: Int) {
val split = container!!.itemCount() > 14
if (split) {
player!!.packetDispatch.sendInterfaceConfig(334, child + 1, false)
player!!.packetDispatch.sendInterfaceConfig(334, child + 2, false)
val messages = arrayOf(
getDisplayMessage(splitList(container.toArray(), 0, 14)), getDisplayMessage(
splitList(
container.toArray(), 14, container.toArray().size
)
)
)
player!!.packetDispatch.sendString(messages[0], 334, child + 1)
player!!.packetDispatch.sendString(messages[1], 334, child + 2)
} else {
player!!.packetDispatch.sendInterfaceConfig(334, child, false)
player!!.packetDispatch.sendString(getDisplayMessage(container.toArray()), 334, child)
}
}
/**
* Method used to get the display message.
* @param items the items.
* @return the message.
*/
private fun getDisplayMessage(items: Array<Item?>): String {
var message = "Absolutely nothing!"
if (items.isNotEmpty()) {
message = ""
for (i in items.indices) {
if (items[i] == null) {
continue
}
message = message + "<col=FF9040>" + items[i]!!.name
if (items[i]!!.amount > 1) {
message = "$message<col=FFFFFF> x "
message = message + "<col=FFFF00>" + getFormattedNumber(items[i]!!.amount) + "<br>"
} else {
message = "$message<br>"
}
}
}
return message
}
/**
* Method used to check if the players & targets have enough space.
* @return `True` if so.
*/
private fun hasSpace(): Boolean {
var hasSpace = true
if (!player!!.inventory.hasSpaceFor(getExtension(target)!!.container)) {
target!!.packetDispatch.sendMessage("Other player doesn't have enough space in their inventory for this trade.")
player!!.packetDispatch.sendMessage("You don't have enough inventory space for this.")
hasSpace = false
} else if (!target!!.inventory.hasSpaceFor(container)) {
player!!.packetDispatch.sendMessage("Other player doesn't have enough space in their inventory for this trade.")
target!!.packetDispatch.sendMessage("You don't have enough inventory space for this.")
hasSpace = false
}
if (!hasSpace) {
setAccepted(false, true)
getExtension(target)!!.setAccepted(false, true)
}
return hasSpace
}
/**
* Gets the formatted number.
* @param amount the amount.
* @return the formatted number.
*/
private fun getFormattedNumber(amount: Int): String {
return DecimalFormat("#,###,##0").format(amount.toLong()).toString()
}
/**
* Method used to give the containers to each participants.
* @param module the module.
*/
private fun giveContainers(module: TradeModule) {
val pContainer: Container? = module.container
val oContainer: Container? = getExtension(module.target)!!.container
SystemLogger.logTrade(module.player!!.username + " -> " + module.target!!.username + " " + Arrays.toString(pContainer!!.toArray()))
SystemLogger.logTrade(module.target!!.username + " -> " + module.player!!.username + " " + Arrays.toString(oContainer!!.toArray()))
(AIRepository.PulseRepository[module.player!!.username.lowercase()]?.botScript as DoublingMoney?)?.itemsReceived(module.target!!, oContainer)
(AIRepository.PulseRepository[module.target!!.username.lowercase()]?.botScript as DoublingMoney?)?.itemsReceived(module.player!!, pContainer)
addContainer(module.player, module.target, oContainer)
addContainer(module.target, module.player, pContainer)
module.target!!.packetDispatch.sendMessage("Accepted trade.")
module.player!!.packetDispatch.sendMessage("Accepted trade.")
}
/**
* Method used to add a container for a player.
* @param player the player who loses the items.
* @param target the target who gains the items.
* @param container the container.
*/
private fun addContainer(player: Player?, target: Player?, container: Container?) {
val c = Container(container!!.itemCount(), ContainerType.ALWAYS_STACK)
c.addAll(container)
var log = "traded => " + target!!.name + " received => {"
for (i in container.toArray()) {
if (i == null) {
continue
}
if (i.amount > player!!.inventory.getMaximumAdd(i)) {
i.amount = player.inventory.getMaximumAdd(i)
}
if (!player.inventory.add(i)) {
GroundItemManager.create(i, player)
}
}
for (i in c.toArray()) {
if (i == null) {
continue
}
log += i.name + " x " + i.amount + ","
}
if (log[log.length - 1] == ',') {
log = log.substring(0, log.length - 1)
}
log += "}"
player!!.monitor.log(log, PlayerMonitor.TRADE_LOG)
}
/**
* Gets the split list as an array.
* @param items the items.
* @param min the min.
* @param max the max.
* @return the split item array.
*/
private fun splitList(items: Array<Item?>, min: Int, max: Int): Array<Item?> {
val list: MutableList<Item?> = ArrayList(20)
for (i in min until max) {
if (items[i] == null) {
continue
}
list.add(items[i])
}
val array = arrayOfNulls<Item>(list.size)
for (i in list.indices) {
if (list[i] == null) {
continue
}
array[i] = list[i]
}
return array
}
/**
* Method used to increment the stage.
*/
fun incrementStage() {
stage++
}
companion object {
/**
* Represents the overlay interface component.
*/
val OVERLAY_INTERFACE = Component(336)
/**
* Represents the main interface component.
*/
val MAIN_INTERFACE: Component = Component(335).setCloseEvent(TradeCloseEvent())
/**
* Represents the "accept" interface component.
*/
val ACCEPT_INTERFACE: Component = Component(334).setCloseEvent(TradeCloseEvent())
/**
* The inventory params for the runscript.
*/
val INVENTORY_PARAMS = arrayOf<Any>(
"",
"",
"",
"Lend",
"Offer-X",
"Offer-All",
"Offer-10",
"Offer-5",
"Offer",
-1,
0,
7,
4,
93,
336 shl 16
)
/**
* The trade params for the run script.
*/
val TRADE_PARAMS = arrayOf<Any>(
"",
"",
"",
"",
"Remove-X",
"Remove-All",
"Remove-10",
"Remove-5",
"Remove",
-1,
0,
7,
4,
90,
335 shl 16 or 30
)
/**
* The partener params for the run script.
*/
val PARTENER_PARAMS = arrayOf<Any>("", "", "", "", "", "", "", "", "", -1, 0, 7, 4, 91, 335 shl 16 or 32)
/**
* Represents the childs that should be hidden.
*/
val HIDDEN_CHILDS = intArrayOf(42, 43, 44, 42, 44, 40, 41)
/**
* Method used to extend the module for each participant.
* @param player the player.
* @param target the target.
*/
fun extend(player: Player?, target: Player?) {
player!!.addExtension(TradeModule::class.java, TradeModule(player, target))
target!!.addExtension(TradeModule::class.java, TradeModule(target, player))
}
/**
* Method used to get the extension from the player.
* @param player the player.
* @return the module instance.
*/
@JvmStatic
fun getExtension(player: Player?): TradeModule? {
return player!!.getExtension(TradeModule::class.java)
}
}
init {
container = TradeContainer(player)
}
}
@@ -342,7 +342,7 @@ public final class Skills {
* Gets the highest combat skill id.
* @return The id of the highest combat skill.
*/
public int getHighestCombatSkill() {
public int getHighestCombatSkillId() {
int id = 0;
int last = 0;
for (int i = 0; i < 5; i++) {
@@ -36,10 +36,10 @@ public final class SystemTermination {
public void terminate() {
SystemLogger.logInfo(this.getClass(), "Initializing termination sequence - do not shutdown!");
try {
SystemLogger.logInfo(this.getClass(), "Stopping all bots...");
AIRepository.clearAllBots();
SystemLogger.logInfo(this.getClass(), "Shutting down networking...");
Server.setRunning(false);
SystemLogger.logInfo(this.getClass(), "Stopping all bots...");
AIRepository.clearAllBots();
Server.getReactor().terminate();
SystemLogger.logInfo(this.getClass(), "Stopping all pulses...");
GameWorld.getMajorUpdateWorker().stop();
@@ -1,88 +0,0 @@
package core.game.world.update.flag.context;
import core.game.node.entity.player.Player;
/**
* Represents a chat message.
* @author Emperor
*/
public class ChatMessage {
/**
* The player reference.
*/
private Player player;
/**
* The chat text.
*/
private String text;
/**
* The effects.
*/
private int effects;
/**
* The numChars.
*/
private int numChars;
public boolean isQuickChat = false;
/**
* Constructs a new {@code ChatMessage} {@code Object}.
* @param player The player.
* @param text The chat text.
* @param effects The chat effects.
* @param numChars The num chars.
*/
public ChatMessage(Player player, String text, int effects, int numChars) {
this.player = player;
this.text = text;
this.effects = effects;
this.numChars = numChars;
}
/**
* Constructs a new {@code ChatMessage.java} {@code Object}.
* @param player the player.
* @param text the text.
*/
public ChatMessage(Player player, String text) {
this.player = player;
this.text = text;
}
/**
* Gets the player.
* @return The player.
*/
public Player getPlayer() {
return player;
}
/**
* Get the chat text.
* @return The chat text.
*/
public String getText() {
return text;
}
/**
* Get the chat effects.
* @return The chat effects.
*/
public int getEffects() {
return effects;
}
/**
* Get the num chars.
* @return The num chars.
*/
public int getNumChars() {
return numChars;
}
}
@@ -0,0 +1,40 @@
package core.game.world.update.flag.context
import core.game.node.entity.player.Player
/**
* Represents a chat message.
* @author Emperor
*/
class ChatMessage
/**
* Constructs a new `ChatMessage` `Object`.
* @param player The player.
* @param text The chat text.
* @param effects The chat effects.
* @param numChars The num chars.
*/(player: Player, text: String, effects: Int, numChars: Int) {
/**
* The player reference.
*/
var player: Player = player
private set
/**
* The chat text.
*/
var text: String = text
private set
/**
* The effects.
*/
var effects = effects
private set
/**
* The numChars.
*/
var numChars = numChars
private set
@JvmField
var isQuickChat = false
}
@@ -53,5 +53,6 @@ public abstract class Script {
bot.getAppearance().sync();
}
// This does not get called and all implementations should be removed
public abstract Script newInstance();
}
@@ -15,7 +15,7 @@ class AIRepository {
val GEOffers = HashMap<Player, GrandExchangeOffer>()
@JvmStatic
val PulseRepository = ArrayList<GeneralBotCreator.BotScriptPulse>()
val PulseRepository = HashMap<String, GeneralBotCreator.BotScriptPulse>() // Lowercase username, pulse
@JvmStatic
fun addItem(item: GroundItem){
@@ -44,7 +44,11 @@ class AIRepository {
}
@JvmStatic fun clearAllBots() {
PulseRepository.toTypedArray().forEach { it.stop(); it.botScript.bot.clear(); AIPlayer.deregister((it.botScript.bot as AIPlayer).uid) }
PulseRepository.forEach { (_, it) ->
it.stop();
it.botScript.bot.clear();
AIPlayer.deregister((it.botScript.bot as AIPlayer).uid)
}
}
}
}
}
@@ -5,6 +5,7 @@ import core.game.system.task.Pulse
import rs09.game.world.GameWorld
import core.game.world.map.Location
import core.tools.RandomFunction
import rs09.Server
import rs09.game.ai.AIPBuilder
import rs09.game.ai.AIPlayer
import rs09.game.ai.AIRepository
@@ -13,14 +14,14 @@ import rs09.game.ai.general.scriptrepository.Script
class GeneralBotCreator {
//org/crandor/net/packet/in/InteractionPacket.java <<< This is a very useful class for learning to code bots
constructor(loc: Location?, botScript: Script) {
constructor(botScript: Script, loc: Location?) {
botScript.bot = AIPBuilder.create(loc)
GameWorld.Pulser.submit(BotScriptPulse(botScript))
}
constructor(botScript: Script, bot: AIPlayer?) {
botScript.bot = bot
GameWorld.Pulser.submit(BotScriptPulse(botScript).also { AIRepository.PulseRepository.add(it) })
GameWorld.Pulser.submit(BotScriptPulse(botScript).also { AIRepository.PulseRepository[it.botScript.bot.username.lowercase()] = it })
}
constructor(botScript: Script, player: Player, isPlayer: Boolean){
@@ -69,13 +70,14 @@ class GeneralBotCreator {
ticks = Integer.MAX_VALUE - 20 //Sets the ticks as high as they can go (safely) and then runs pulse again
pulse() //to trigger the transition pulse to be submitted.
super.stop()
AIRepository.PulseRepository.remove(this)
if (Server.running) AIRepository.PulseRepository.remove(this.botScript.bot.username.lowercase())
}
}
inner class TransitionPulse(val script: Script) : Pulse(RandomFunction.random(60,200)){
override fun pulse(): Boolean {
GameWorld.Pulser.submit(BotScriptPulse(script.newInstance()).also { AIRepository.PulseRepository.add(it) })
// This does not get called and should be removed
GameWorld.Pulser.submit(BotScriptPulse(script.newInstance()).also { AIRepository.PulseRepository[it.botScript.bot.username.lowercase()] = it })
return true
}
}
@@ -30,6 +30,8 @@ import core.game.world.update.flag.player.ChatFlag
import core.tools.RandomFunction
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.rs09.consts.Items
import rs09.ServerConstants.Companion.SERVER_GE_NAME
import rs09.game.ai.AIRepository
@@ -44,6 +46,8 @@ import rs09.game.world.repository.Repository
import rs09.tools.stringtools.colorize
import java.util.*
import java.util.concurrent.CountDownLatch
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sqrt
@@ -734,6 +738,64 @@ class ScriptAPI(private val bot: Player) {
bot.inventory.add(item)
}
/**
* Method to equip list of items and set stats
* Useful for starting a bot up
* @param items the list of items to equip
* @author dginovker
*/
fun equipAndSetStats(items: List<Item>?){
if (items == null) return
for(item in items){
equipAndSetStats(item)
}
}
/**
* Method to equip a single item and set stats
* Useful for starting a bot up
* @param item the item to equip
* @author dginovker
*/
fun equipAndSetStats(item: Item){
val configs = item.definition.handlers
val slot = configs["equipment_slot"] ?: return
bot.equipment.add(item, slot as Int,
false,false)
val reqs = configs["requirements"]
if(reqs != null)
for(req in configs["requirements"] as HashMap<Int,Int>)
bot.skills.setStaticLevel(req.key, req.value)
bot.skills.updateCombatLevel()
}
/**
* Method to load appearance and equipment from JSON
* Useful for starting a bot up
* @param json the JSON object to load from (dumped via ::dumpappearance)
* @author dginovker
*/
fun loadAppearanceAndEquipment(json: JSONObject?) {
if (json == null) return
bot.equipment.clear()
bot.appearance.parse(json["appearance"] as JSONObject)
val equipment = json["equipment"] as JSONArray
bot.equipment.parse(equipment)
bot.appearance.sync()
for (i in 0 until bot.equipment.capacity()) {
val item = bot.equipment.get(i)
if (item != null) {
equipAndSetStats(item)
}
}
// Set all combat stats to a function of the highest combat stat(otherwise you end up with lopsided stats)
val highestCombatSkill = bot.skills.getStaticLevel(bot.skills.highestCombatSkillId)
for (i in 0 until 7) {
bot.skills.setStaticLevel(i, max((highestCombatSkill * 0.75).toInt(), bot.skills.getStaticLevel(i)))
}
bot.skills.updateCombatLevel()
}
fun getOverlay(): BottingOverlay{
return BottingOverlay(bot)
}
@@ -0,0 +1,376 @@
package rs09.game.ai.general.scriptrepository
import core.game.container.Container
import core.game.interaction.Option._P_TRADE
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.request.trade.TradeModule
import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.update.flag.context.ChatMessage
import core.game.world.update.flag.player.ChatFlag
import discord.Discord
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
import org.rs09.consts.Items
import rs09.ServerConstants
import rs09.game.ai.AIRepository
import rs09.game.ai.general.scriptrepository.Adventurer.Companion.lumbridge
import rs09.game.interaction.IntType
import rs09.game.interaction.InteractionListeners
import rs09.game.world.ImmerseWorld
import java.io.File
import java.io.FileReader
import java.util.Random
import kotlin.math.min
/**
* A bot that doubles money
* 30% chance to double money, 70% chance to scam
* @author dginovker
*/
class DoublingMoney : Script() {
/**
* If we're in ScamMode, we will never trade away any more coins
*/
private var scamMode = false
/**
* Whether the bot has run its setup (gotten appearance made/etc.)
*/
private var setup = false
/**
* Player who most recently traded with this bot
*/
var victim: Player? = null
/**
* Player who the bot took money from
*/
private var playerOwed: Player? = null
/**
* Whether we sent a trade request to the player we owe yet
*/
private var sentTradeRequest = false
/**
* Amount the bot owes the player (2x the amount the player gave the bot)
*/
private var debtOwed: Int = 0
/**
* How many ticks the bot has run for
*/
var ticks = 0
/**
* Duration for how long the bot will take a nap
*/
private var sleepTime = 0
/**
* Debug information about what state the bot is in
*/
private var stateString = "init"
/**
* How long the bot will stay around for
*/
private val maxTicks = (400..750).random()
enum class Effort {
LOW,
HIGH,
VERY_HIGH
}
/**
* Characteristics about how hard the bot will work
* Most likely to be LOW, small chance to be HIGH, very small chance to be VERY_HIGH
*/
private val effort = when (Random().nextInt(100)) {
in 0..90 -> Effort.LOW
in 90..98 -> Effort.HIGH
else -> Effort.VERY_HIGH
}
// Priority calculation -> Execute method mapping. Priority calculation with the highest return value is executed
var states = mapOf(
fun(): Int {
if (setup) return -1
return 250
} to {
stateString = "Putting on my outfit.."
var appearance = if (Math.random() < 0.5) "noob" else "intermediate"
if (effort == Effort.VERY_HIGH && Math.random() < 0.5) appearance = "veteran"
val appearancesArray = botAppearances[appearance] as JSONArray
scriptAPI.loadAppearanceAndEquipment(appearancesArray.random() as JSONObject)
setup = true
},
fun(): Int {
val botTradeModule = TradeModule.getExtension(bot)
if (botTradeModule != null) return -1
return 0
} to {
stateString = "Doing nothing"
},
fun(): Int {
return 1
} to {
stateString = "Saying Doubling money"
when (effort) {
Effort.LOW -> {
scriptAPI.sendChat("Doubling money")
sleepTime = 7
}
Effort.HIGH -> {
val message = arrayOf("Doubling Money", "Doubling Money", "Doubling Money!", "Doubling moneyy").random()
val messageEffect = arrayOf(0, 256).random()
val ctx = ChatMessage(bot, message, messageEffect, message.length)
bot.updateMasks.register(ChatFlag(ctx))
sleepTime = 8
}
Effort.VERY_HIGH -> {
val message = arrayOf("Doubling money!", "Doubling money").random()
val messageEffect = arrayOf(771, 2818, 2562, 768, 512, 2304, 2560, 769, 1792).random()
val ctx = ChatMessage(bot, message, messageEffect, message.length)
bot.updateMasks.register(ChatFlag(ctx))
sleepTime = 9
}
}
},
fun(): Int {
if (victim == null) return -1
return 10
} to {
stateString = "Accepting trade request"
// Send trade request back to victim
InteractionListeners.run(-1, IntType.PLAYER, "trade with", bot, victim!!)
victim = null
sleepTime = 3
},
fun(): Int {
if (debtOwed >= 0) return -1
val botTradeModule = TradeModule.getExtension(bot) ?: return -1
val playerTradeModule = TradeModule.getExtension(botTradeModule.target) ?: return -1
if (!playerTradeModule.container!!.containsAtLeastOneItem(Items.COINS_995)) return 15
return -1
} to {
val botTradeModule = TradeModule.getExtension(bot)
stateString = "Waiting for ${botTradeModule!!.target} to post money"
sleepTime = 5
},
fun(): Int {
// If we have debt and are in the trade screen with the player who we owe, but have not put up coins, put up coins
if (debtOwed == 0) return -1
val botTradeModule = TradeModule.getExtension(bot) ?: return -1
if (botTradeModule.target != playerOwed) return -1
if (!botTradeModule.container!!.containsAtLeastOneItem(Items.COINS_995)) return 150
return -1
} to {
stateString = "Paying off ${playerOwed!!.username} $debtOwed coins"
val botTradeModule = TradeModule.getExtension(bot)
val coinSlot = bot.inventory.getSlot(Item(Items.COINS_995))
botTradeModule!!.container!!.offer(coinSlot, debtOwed)
debtOwed = 0
playerOwed = null
},
fun(): Int {
val botTradeModule = TradeModule.getExtension(bot) ?: return -1
val playerTradeModule = TradeModule.getExtension(botTradeModule.target) ?: return -1
if (botTradeModule.container!!.containsAtLeastOneItem(Items.COINS_995)) return 200
if (playerTradeModule.container!!.containsAtLeastOneItem(Items.COINS_995)) return 200
return -1
} to {
stateString = "Accepting any trade screen that has coins put up"
val botTradeModule = TradeModule.getExtension(bot)
val playerTradeModule = TradeModule.getExtension(botTradeModule!!.target)
if (botTradeModule.isAccepted) return@to
sleepTime = (1..if (botTradeModule.getInterface() == TradeModule.MAIN_INTERFACE) 2 else 5).random()
val coinsFromBot = botTradeModule.container!!.getAmount(Items.COINS_995)
if (botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE && coinsFromBot > 0 && effort == Effort.VERY_HIGH) {
val message = "Payed ${(if (coinsFromBot < 1000) "${coinsFromBot}gp" else "${coinsFromBot / 1000}k")}"
val ctx = ChatMessage(bot, message, 512, message.length)
bot.updateMasks.register(ChatFlag(ctx))
sleepTime = 7
}
if (botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE && Math.random() < 0.2 && effort == Effort.HIGH && coinsFromBot > 0) {
scriptAPI.sendChat("Enjoy")
sleepTime += 4
}
if (botTradeModule.getInterface() == TradeModule.MAIN_INTERFACE && scamMode) {
sleepTime = maxOf(3, sleepTime)
}
if (botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE) {
val player = botTradeModule.target
var playerNetPoL = player!!.getAttribute("double-money-net-pol", "0").toInt()
playerNetPoL += coinsFromBot
playerNetPoL -= playerTradeModule!!.container!!.getAmount(Items.COINS_995)
player.setAttribute("double-money-net-pol", playerNetPoL.toString())
// if playerNetPoL > 100k, send a Discord notification
if (playerNetPoL > 100_000) {
Discord.postPlayerAlert(player.username, "Made too much off Doubling Money bots: ${playerNetPoL / 1000}k")
}
}
// If we're in scamMode, we cannot actually setAccepted to true if we're giving away coins! (Gotta fake em out ;)
if (scamMode && botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE && coinsFromBot > 0) {
botTradeModule.decline()
} else {
botTradeModule.setAccepted(true, update = true)
}
sentTradeRequest = false
},
fun(): Int {
if (sentTradeRequest) return 50
return -1
} to {
// Wait for the other player to accept
},
fun(): Int {
if (TradeModule.getExtension(bot) == null && debtOwed > 0 && playerOwed != null) return 25
return -1
} to {
// Scam over 200k payout or 70% chance
if (Math.random() < 0.7 || debtOwed > 200_000) {
stateString = "Scamming"
scamMode = true
if (effort != Effort.VERY_HIGH || Math.random() < 0.5) {
// At high scam effort, there's a chance we fake giving them coins back to keep milking
// with scamMode = true, we will never accept giving coins away at the second trade screen again
terminate()
}
}
stateString = "Sending trade request to ${playerOwed!!.name} to give them $debtOwed coins"
playerOwed!!.interaction.handle(bot, _P_TRADE)
InteractionListeners.run(-1, IntType.PLAYER, "trade with", bot, playerOwed!!)
sentTradeRequest = true
},
fun(): Int {
// If we're not near a doubling loc, or another doubling bot is on our loc, walk to random one
var minDist = 1000.0
for (loc in doublingLocs) {
minDist = min(minDist, loc.getDistance(bot.location))
}
if (minDist > 1) return 2
RegionManager.forId(bot.location.regionId).planes[bot.location.z].players.forEach {
if (AIRepository.PulseRepository[it?.username?.lowercase()]?.botScript is DoublingMoney
&& it != bot
&& it.location.getDistance(bot.location) <= 1) {
return 2
}
}
return -1
} to {
stateString = "Walking to doubling location"
val loc = doublingLocs.random()
scriptAPI.walkTo(loc)
sleepTime = 5
},
fun(): Int {
// If we're past the max ticks, log out
if (ticks > maxTicks) return 30
return -1
} to {
stateString = "Logging out"
terminate()
},
fun(): Int {
// If we're past 1,000 ticks, force terminate
if (ticks > 1000) return 1_000_000
return -1
} to {
stateString = "Force terminating"
terminate()
}
)
override fun toString(): String {
return "stateString: $stateString, sleepTime: $sleepTime, ticks: $ticks, maxTicks: $maxTicks, debtOwed: $debtOwed, playerOwed: $playerOwed, victim: $victim, effort: $effort, scamMode: $scamMode"
}
override fun tick() {
if(!bot.isActive){
running = false
return
}
ticks ++
if (sleepTime > 0) {
sleepTime --
return
}
// Execute the priority calculations, then execute the method of the one which returned highest
states.maxByOrNull { it.key() }?.value?.invoke()
}
fun tradeReceived(p: Player) {
victim = p
}
fun itemsReceived(p: Player, container: Container?) {
if (container == null) return
val coins: Item = container.get(Item(Items.COINS_995)) ?: return
playerOwed = p
debtOwed = coins.amount * 2
if (effort == Effort.VERY_HIGH) {
val message = "Received ${(if (coins.amount < 1000) "${coins.amount}gp" else "${coins.amount / 1000}k")}"
val ctx = ChatMessage(bot, message, 256, message.length)
bot.updateMasks.register(ChatFlag(ctx))
}
}
fun terminate() {
scriptAPI.teleport(lumbridge)
debtOwed = 0
bot.isActive = false
sleepTime = 500
AIRepository.PulseRepository.remove(bot.username.lowercase())
ImmerseWorld.spawnDoubleMoneyBot(true)
}
override fun newInstance(): Script? {
// this straight doesn't get called....
return null
}
init {
skills[Skills.AGILITY] = 99
inventory.add(Item(Items.COINS_995, 1_000_000))
}
companion object {
val startingLocs = arrayOf(Location.create(3184, 3488, 0),
Location.create(3167, 3461, 0),
Location.create(3170, 3444, 0),
Location.create(3165, 3487, 0),
Location.create(3167, 3489, 0),
Location.create(3162, 3491, 0))
val doublingLocs = arrayOf(Location.create(3159, 3492, 0),
Location.create(3164, 3484, 0),
Location.create(3169, 3486, 0),
Location.create(3172, 3489, 0),
Location.create(3168, 3483, 0),
Location.create(3166, 3493, 0),
Location.create(3157, 3498, 0),
Location.create(3157, 3485, 0)
)
// load from data/botdata/ge_bot_appearances_and_equipment.json
private val jsonFilePath = "${ServerConstants.BOT_DATA_PATH}/ge_bot_appearances_and_equipment.json"
private val jsonFile = File(jsonFilePath)
private val parser = JSONParser()
val botAppearances = parser.parse(FileReader(jsonFile)) as JSONObject
}
}
@@ -7,7 +7,6 @@ import core.tools.RandomFunction
import org.rs09.consts.Items
import rs09.game.ai.general.GeneralBotCreator
import rs09.game.content.global.worldevents.shootingstar.ShootingStarPlugin
import rs09.game.interaction.InteractionListener
import rs09.game.interaction.IntType
import rs09.game.interaction.InteractionListeners
@@ -88,7 +87,7 @@ class ShootingStarBot : Script() {
val spawnLoc = Location.create(2230, 3339, 0)
fun new() : ShootingStarBot {
val script = ShootingStarBot()
GeneralBotCreator(spawnLoc, script)
GeneralBotCreator(script, spawnLoc)
return script
}
}
@@ -49,11 +49,11 @@ object QCRepository {
builder.rank = player.details.rights.ordinal
publish(builder.build())
} else {
val ctx = ChatMessage(player, qcString, 0, qcString.length)
val ctx = ChatMessage(player!!, qcString, 0, qcString.length)
ctx.isQuickChat = true
Pulser.submit(object : Pulse(0, player) {
override fun pulse(): Boolean {
player!!.updateMasks.register(ChatFlag(ctx))
player.updateMasks.register(ChatFlag(ctx))
return true
}
})
@@ -1,6 +1,7 @@
package rs09.game.system.command.sets
import api.*
import com.google.gson.JsonObject
import core.game.content.quest.tutorials.tutorialisland.CharacterDesign
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
@@ -9,13 +10,18 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import org.json.simple.JSONObject
import rs09.game.content.dialogue.DialogueFile
import rs09.game.interaction.InteractionListeners
import rs09.game.interaction.SpadeDigListener
import rs09.game.node.entity.player.info.login.PlayerSaver
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
import rs09.game.world.GameWorld
import rs09.tools.END_DIALOGUE
import java.awt.HeadlessException
import java.awt.Toolkit
import java.awt.datatransfer.StringSelection
import java.util.*
@Initializable
@@ -125,6 +131,24 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) {
CharacterDesign.open(player)
}
/**
* Copies your current appearance and equipment as JSON to the clipboard
*/
define("dumpappearance", Privilege.MODERATOR){ player, _ ->
val json = JSONObject()
PlayerSaver(player).saveAppearance(json);
val equipJson = PlayerSaver(player).saveContainer(player.equipment)
json["equipment"] = equipJson
val jsonString = json.toJSONString()
try {
val clpbrd = Toolkit.getDefaultToolkit().systemClipboard
clpbrd.setContents(StringSelection(jsonString), null)
notify(player, "Appearance and equipment copied to clipboard.")
} catch (e: HeadlessException) {
reject(player, "NOTE: Paste will not be available due to remote server.")
}
}
/**
* Bury inventory at current location
*/
@@ -200,8 +200,9 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
define("botinfo", Privilege.STANDARD, "::botinfo <lt>botname<gt>", "Prints debug information about a bot"){ player, args ->
val scriptInstances = AIRepository.PulseRepository
// Find the bot with the given name (non-case sensitive)
val bot = scriptInstances.find { it.botScript.bot.username.equals(args[1], true) }
// Find the bot with the given name (non-case sensitive, concat args by space)
val botName = args.slice(1 until args.size).joinToString(" ").lowercase()
val bot = scriptInstances[botName]
if (bot == null) {
reject(player, "No bot with that name found.")
return@define
@@ -309,5 +309,25 @@ class ModerationCommandSet : CommandSet(Privilege.MODERATOR){
}
}
}
define("getattribute", Privilege.ADMIN, "::getattribute <lt>username<gt> <lt>attribute<gt>", "Gets the value of an attribute for a player.") {player, args ->
val username = args.getOrNull(1) ?: ""
val attribute = args.getOrNull(2) ?: ""
if (username.isEmpty() || attribute.isEmpty()) {
reject(player, "Usage: ::getattribute username attribute")
return@define
}
val p = Repository.getPlayerByName(username)
if (p == null) {
reject(player, "Unable to find player $username.")
return@define
}
val value = p.getAttribute<Any>(attribute)
if (value == null) {
reject(player, "Unable to find attribute $attribute for player $username.")
return@define
}
notify(player, "Attribute $attribute for player $username is $value.")
}
}
}
@@ -75,6 +75,7 @@ object ServerConfigParser {
increased_door_time = data.getBoolean("world.increased_door_time"),
enabled_botting = data.getBoolean("world.enable_botting"),
max_adv_bots = data.getLong("world.max_adv_bots").toInt(),
enable_doubling_money_scammers = data.getBoolean("world.enable_doubling_money_scammers", false),
wild_pvp_enabled = data.getBoolean("world.wild_pvp_enabled"),
jad_practice_enabled = data.getBoolean("world.jad_practice_enabled"),
message_model = data.getString("world.motw_identifier").toInt(),
@@ -79,6 +79,7 @@ class GameSettings
var increased_door_time: Boolean,
var enabled_botting : Boolean,
var max_adv_bots: Int,
var enable_doubling_money_scammers: Boolean,
var wild_pvp_enabled: Boolean,
var jad_practice_enabled: Boolean,
@@ -132,6 +133,7 @@ class GameSettings
val increased_door_time = if(data.containsKey("increased_door_time")) data["increased_door_time"] as Boolean else false
val enable_botting = if(data.containsKey("botting_enabled")) data["botting_enabled"] as Boolean else false
val max_adv_bots = if(data.containsKey("max_adv_bots")) data["max_adv_bots"].toString().toInt() else 100
val enable_doubling_money_scammers = if(data.containsKey("enable_doubling_money_scammers")) data["enable_doubling_money_scammers"] as Boolean else false
val wild_pvp_enabled = if(data.containsKey("wild_pvp_enabled")) data["wild_pvp_enabled"] as Boolean else true
val jad_practice_enabled = if(data.containsKey("jad_practice_enabled")) data["jad_practice_enabled"] as Boolean else true
val allow_token_purchase = data["allow_token_purchase"] as Boolean
@@ -160,6 +162,7 @@ class GameSettings
increased_door_time,
enable_botting,
max_adv_bots,
enable_doubling_money_scammers,
wild_pvp_enabled,
jad_practice_enabled,
message_of_the_week_identifier,
@@ -35,6 +35,7 @@ class ImmerseWorld : StartupListener {
immerseFishingGuild()
immerseAdventurer()
// immerseSlayer()
immerseGE()
}
}
}
@@ -64,7 +65,7 @@ class ImmerseWorld : StartupListener {
fun immerseFishingGuild() {
val fishingGuild = Location.create(2604, 3421, 0)
for (i in (0..4)) {
GeneralBotCreator(fishingGuild, SharkCatcher())
GeneralBotCreator(SharkCatcher(), fishingGuild)
}
}
@@ -85,7 +86,7 @@ class ImmerseWorld : StartupListener {
GlassBlowingBankstander(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2807, 3441, 0))
)
GeneralBotCreator(Location.create(2805, 3435, 0), LobsterCatcher())
GeneralBotCreator(LobsterCatcher(), Location.create(2805, 3435, 0))
}
fun immerseLumbridgeDraynor() {
@@ -220,5 +221,20 @@ class ImmerseWorld : StartupListener {
)
)
}
private fun immerseGE() {
spawnDoubleMoneyBot(false)
}
fun spawnDoubleMoneyBot(delay: Boolean) {
if (GameWorld.settings?.enable_doubling_money_scammers != true) return
val random: Long = (10_000..7_200_000).random().toLong()
Timer().schedule(if (delay) random else 0) {
GeneralBotCreator (
DoublingMoney(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, DoublingMoney.startingLocs.random())
)
}
}
}
}
+2 -1
View File
@@ -46,6 +46,7 @@ skillcape_perks = false
increased_door_time = false
enable_botting = false
max_adv_bots = 100
enable_doubling_money_scammers = true
wild_pvp_enabled = false
jad_practice_enabled = false
personalized_shops = false
@@ -77,4 +78,4 @@ object_parser_path = "@data/ObjectParser.xml"
#path logs are written to
logs_path = "@data/logs"
bot_data = "@data/botdata"
eco_data = "@data/eco"
eco_data = "@data/eco"
+1
View File
@@ -59,6 +59,7 @@ skillcape_perks = true
increased_door_time = false
enable_botting = false
max_adv_bots = 100
enable_doubling_money_scammers = true
wild_pvp_enabled = false
jad_practice_enabled = true
personalized_shops = true