Merge branch 'develop' into feature/clans-season-3

This commit is contained in:
Alexander Meech 2017-06-16 16:25:57 -04:00 committed by GitHub
commit 7a2864a701
278 changed files with 21379 additions and 1515 deletions

View File

@ -24,7 +24,8 @@ public enum Rank
MODERATOR("Mod", "mod", ChatColor.GOLD, "Moderators enforce rules and provide help to \nanyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 32, DyeColor.ORANGE),
HELPER("Trainee", "train", ChatColor.GOLD, "Trainees are moderators-in-training. \nTheir duties include enforcing the rules and \nproviding help to anyone with questions or concerns. \n\nFor assistance, contact them using " + F.elem("/a <message>") + ".", 24, DyeColor.ORANGE),
MAPLEAD("MapLead", "mapl", ChatColor.BLUE, "Map Leaders are leaders of the Mineplex Build Team. \nThey oversee the creation of new maps and manage Builders.", 25, DyeColor.BLUE),
MAPDEV("Builder", "mapd", ChatColor.BLUE, "Builders are members of the Mineplex Build Team. \nThey create many of the maps used across Mineplex.", 26, DyeColor.BLUE),
MAPPER("Mapper", "mapp", ChatColor.BLUE, "These senior staff members work closely with \nthe development and design teams to build new \nmaps for new and old content!", 100, DyeColor.BLUE),
MAPDEV("Builder", "mapd", ChatColor.BLUE, "These creative staff members help \nbuild maps for your favorite games!", 26, DyeColor.BLUE),
MEDIA("Media", "media", ChatColor.BLUE, "The Media rank is given to talented artists who are\n endorsed to create content for Mineplex.", -1, DyeColor.BLUE),
EVENT("Event", "evnt", ChatColor.WHITE, "A member of the official Mineplex Events team!", -1, DyeColor.WHITE),

View File

@ -69,6 +69,16 @@ public class SkinData
public final static SkinData SLENDERMAN = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTA0NzUyNzk4NTUsInByb2ZpbGVJZCI6IjlmY2FlZDhiMTRiNTRmN2ZhNjRjYjYwNDBlNzA1MjcyIiwicHJvZmlsZU5hbWUiOiJMQ2FzdHIxIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9hMWNkOTI5OTFmYTRjZGQ2MGVlZDNhZTM3ZmI5NWRmZjFkNWNkOGNiZmYwYWFjMzE4MmQ0ODU2NDU5NTIzYyJ9fX0=", "OVqWFLCekyZcdGli6kPBKNh8/VYPhKZGNqlAvSOKc3RLgh4pIkI6TDPr/Y+VQdhz1wZozARFYSeoDJJJ4nZTi7gi3rVPG2rL1ZnKo7so5hdT8caEzSTRmgwPKzo03ZhEEsW9AEJo9mpiUxGSJdBlgEb9UgodpYFW1IjRC09CcBUqzRWP8QGZTSFSN5x9emQ97DyiFmt0NFWubHCKHdb7CExhchPRtbahL3hOEzPY8/Y+Irl9OZjx7jONE7O/sYItCuZoXc3FaTgCV0riiXHCgH2eA54s5TQVWumtp3FU7VIcKR6pm/o61+GusvqhNgdFNk9XSHWMUyp+HNU0R8sConZQN/eaVx9laJmUUb4zNZ7hX/hLYV+r9LFU1NXOeIZWJPShD+bYfZgEorIpD+EAL4BHht/f5e6a1IZUDBWb001PFibby2t9WWjoDVKz4McbxZ2Xui7EHKFG1K3biPibhWx6fvnOeJ2xW6UDIZcD+TCXwlW/knkFt44Xpyv3oNHk3UNkyrQgghd6qkc3gZHxP8PQCNvKIyK1I+pHR6JMZvSStp7ZQRDpvsvIUyOJvq+7Bs7lFYs8hcJHMzEB+8PYlH2k7P7iLuA6ZYFUmvOW1LLq0+hvxK96ZdNEsJdmMkVVTZBRw7vsZ4GPbkdp2cMOFH2lHcQj80xKqVbd43IqFDA=");
public final static SkinData BOB_ROSS = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTU2NjEyOTc2NTcsInByb2ZpbGVJZCI6IjdkYTJhYjNhOTNjYTQ4ZWU4MzA0OGFmYzNiODBlNjhlIiwicHJvZmlsZU5hbWUiOiJHb2xkYXBmZWwiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzVhNzZhN2NlMzZlZGRiYmZhNWMzMmJhZmVhYmUyNmQ3ZWJlNWRlOTBkNzYyYzJmNWY3OTQ1ZTQ1ODUxOTU2ZDYifX19", "b7pUQSZ1UkMZJNSqdaBPGWfm+rfvFkEh58pBvYTG2RBPwVju1kKinb1LfsyYhFKlyPvL1jfqi30udmb0302QvE0SKg7p3txxULa3Hr94+eCJWFxrOxUNorRT9E+TurJxH6jimu6KW1p6goPn77/kgNaWb9xn3+E84+vH0z9ETjgc5G0aYLT+cSzThUorhvOQ7DRLfRgSWiFxfm3Er0g+waLfDEeNNAd6OJ5k3X+kgM/+V6QTIFofnZZ6NdZZInTARAVol2H0pRfQfAuVYfJyVyvA0uF+ZX+wlMuBTG1MeyWjZgI1iUKmGaQADXsAV796kT+Z+tAXpbRYYYZnxil5jx5P4druiHvaQfV2KK3lbKm2uH9M3SZr5d57C3V24BKRRWGS4C9INzgO8ORIIomes7kp0gECS4MnSMI6hcl0JsXVlaAy88BgmT/PKxM+3q4PCQE1N9fTCuhoil7vVYIU3uBXwFUE7NTAOUdBee+3TtMstIu2WP8rtEZBVpGH9CmomaLTCzPZSdXGY31goOFXSRYMNi8j4ykuBgP0qJqimipWH0rBF1bMdHqMu359h62tTLRKipHWXPxj4N8c/n1CVPYjuXH9X3f1HAU4DnET+v93Vb/uzbx8rXFrz6jLPwAjSlJ8Th3VE+4ey/ZBHWPB+SuHetN+e0r/LYxiqwwlnwI=");
public static final SkinData HATTORI = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjEyMTczMDgsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS83MjczMTBiMzlhMTIzOWI3ZTI4Y2JjNTkzMWY1MzlkNGVlNmQxOTc3ODhjNWI1YTY3YWY1NDJlYzk0MmZkMyJ9fX0=", "aHfFqPOZmcQkUqFPjVa27h27k5gyvkZMCOyIaIdIZfqVDg/69/hakkDQazvKg/U8KTlYaDSRyOp9ZD5qOUSCPvRtRDMhuX/Tn68KD9BdW5jYKsXo0puOa7IJDKAE47z7YQ8AvfOtxuOAg6S0ihjYEQqRA56UQ+gPbkd+pxpMxvXoLyAx7IEIKWmlkibG/rmaX8J7OEgq8Wi9s6BhtPVNMaLoznzdzOiiYkcza/zEG5zMXnj/hFHHUpWrYff0Oj7/SUB+krLsiMficASzzs/9HZq81V0ketqUhJYX66HL8F5fQniP8kYu9LbNNcVJmtlER03QaEqP/H8udemlVskFkOYLkTmhxfSetL46N+ZVf0Sxp2xYcFOH3djH/Q26IIXtzEqVyUW5Gun/ZJp8B8zYMOXbXSmaALAYPoX9cs91ZilNX/W7zn7b5Kb9kUBGt58eUpKoXjgK7rSvmH0X2JOZGFVji5QKzp/eOQAqMhkBOU8sEm9AT6mfZjjlyIDOZxSX6hjEJXRVVzFFlzTiRPTcAtaHWRnlRFywsDDSgVBGvQMPNMNa6CFeo0ajnhmfHWa4Ga77kpfQ75PzOoJ/j6Z/2sSIHfQFWE6INAGAyypX/x0Fd/AH6SmYfilnX6lhtd7OsDlxS01QGoRLPBh/ol+wY6rHSM1N6Qta0ulpQZLYIms=");
public static final SkinData ANATH = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0Njg4NjM4MTYsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS81NGI5NGQ4NzE5ZWFhYjc0YjVhMzhjN2Q5NDliM2FkMmIyYzA0ODIxZGY4OWM1ZDA0YjY5ZjNjZmExYmJhNjUifX19", "IKlnXzQ2k57XyTHge5V2ttnV1AqbRKrV0JktZS4+nLXx+ROM77/HRuf3/bYTqg48SB8npXy+c6nLYTCY1fTZOl3t2puS6BpZMBXuTV//A0OMQ1pJKzDb8vW6CwPYw2Nu6o0QX3J/FeUIaBj16GZAPxXOtSekkeOw9qsdh57GyqSmzODlEA/7CnJWqX2Ani5DACzo6j5rzfsz2qRgOzVlnbVlVzpXicRuYYLxKvT4nMS+B3HpQdsyFKAx8nTO/GmCHDzW97jck6w/VDlW9x+J39tPDEaKPLbDz1YV59yJt6hjNAcnwgbf3KvHSAbGZNLqRegq/Rk20ZI2J5GYT5ipiyf+p8rHfkRTxIsVCMyVecnSKaz59YQ7AleiWVGzYHDETU702UyigAZFHGHQ/0Kj9UyyZ4ew228FQuGo7iGY4dS/PKq40d1v3fq+czwBhcXR+Msi1Zqg/4dTh+QwwwWsIS3CKtOInpJgZ3U/tkn4STB3o+oKBbmBWvpJk8SrA6DVKKJMjHQig+67hXKSbdcRUWAoGc/iuRhRXgILkC99Ot4PHohEbwbEW8MsKxm49OFqzP4zptaUaiQpMK4YCxENhLrI7X+w51tt2XTjroIHu4oLYS4pG16ZnhUmd/RFg8Ar7mBVOv/2lUtOO5aMAv88CpyD+XXNcCQB4G5pv4c0F14=");
public static final SkinData DEVON = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0Njk0NDE1MDYsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS85N2FkNjY1MjFmNzNjOWFmYzE4MzliZGExYzE5ZDNkMjg3YjNmMjRmY2EwZTBlMTE1NzhiOTE0ZTNiNWIwZDIifX19", "BNIc7N3SGIXOEUKFe3hrQp4YmniPxkiL5aKAUNkTmYqbygAQlrCCrwJTuK6JrzkWmD5AzMSzMDKkmoMWOikgulhSmDyC88lQz/LQH3co7WldPHaPL6kk27ZirmIIZEm5WKcvWhQ7ChNWQd2KsZuFqxZSdLSQmsbujF9vpuVbhlU4hajsUwbdiOJRZ18fOAFoJYq/g3RlvqC9VtAA/IAAN7jIpXf9Pn5+vjLqN+AdKm27YknCpqMtBfkYaIhMrpTBe2gP+o50TmH0xm0IZPCS+ORYNGwFdCsg6DzEU7a0rtcUdcZgdInc09mS8tMY9eeMAISYYq5MpyliHQ/areGKk0RJEYg7muc9r/N6vBUpxZtZH8BioDj2dNj4JOoH/58cwU3+hv/Woykc9o5NUPyz0nndiOtTUp1SaDXleKyHryoYnIkPyaDPyuA7qTbIKZQHxyAdrRsnknb0PYku6T8RA4kWNK2jlOH+R9D4eiKFcbLRU2Zl6L57lJTZFFI6GUvzDsyD/vBb59gjvXYzRmvguX9CHUc1aLDeUKhV8NFXeaonoYM9VPIUBQRWNdMery9OlBiQvg4VXy1w2yKLvlHRhJZJpDm/IDdsfg27o8+BUOZ0xHF9iXPBDkOiLXXZ02X4IonLcopVNImCMRZJ1dKHwgu9qnFqVTEKH4mwXUz2Zq8=");
public static final SkinData DANA = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjkyMzgxMDAsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9hOWRhYTg5OGVkN2E0N2YyOGFkMjVmNjk5Y2Y4MzQyODFmMTVkZTY5OWM1MWVhMTRkOWRlYzVhM2VlNzY1MiJ9fX0=", "KUI3h0MDUNWQ3avjozkw0KnZf1UAMkRHzRKY9yGS/iUh9EMmDbfLcRfBhUvR5Dd6//75Yw2tElBrvPx+VqfJk0LqMACQc71n0lDY1NzqnXbpf6vNGyuhyumjhMSjJTG3BJ8Qtdd1yCsPK2x5ym+cGPS1FevJj4Vcu6rxg9HXZokgfjD11NXEwulFuPIiWHpJlnd8NlBw4a3txlrVwDnaHo7GqYSJeM1uOCrdICdpThSA2N2mOUEmOHvH9rHUhQvkKHipbsQMIxIX4oiXDWeK6P/GtT+Iv0DIeJfQdDkhDiIG5/zUyxmpC2mma1FQIsFsQOaJfgYZLfcOXGdhwlL/OcZ9ULBIKhgSx7Ozwzsc+JKonqlaBOuaietq5z/XvMClgFG9U2a1LXc5BIgaN/ClsO0uTksuoA8H0SDx9k3EmOjaPdrJOsQ/fgWQSkWN2XniLLFiEtSOEOI58vw6ORVXDgjbP+TqD0b6/d10z0jUzS2FD7AO51LHzTw+BjqoyVef4fszNNSqMi5QEgfBl++EAolZBAMHgN7hq6k52ry2LPlO5L8sm6NoZ4DrLyrx1oFNtXZZgYvNVy7rtEpIDdQczwAZkJFV0fuz8tRH3CkW/roA5HbfX3Fv19mQoteoemrSUrOwLlQsyVPxsFsn8uX94Cw88Q5KgBCGmGY2vpXHuiI=");
public static final SkinData BARDOLF = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjkxMTE4NjEsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS84MjUxNjZmNzc0ZjcyNmZmMDE3NTQ3OTk0NDc0MGYxNjRmMTZmYmI2M2I3NGI3NmNmNzk0NDMxZGZkNzUyIn19fQ==", "W8TO4M/IQ4rQ91627EaudboKwR8TuKTp5mAYOCyOJLCD0vyyEJmnZFy1Hv9HlXKiXsEm9iC36+cmQ8JfSE0JlIfU2vRH5qbXUL4HUHZi20SHVA5YKM2ztxI9uouc14ctv8pxlhT/huKxYNgB/eJR+ckT1gyc78RBoJj5YLwUTsptO87KE/vFg9hbHVo5lVSdk//jhfDsMRyf0RXp/wKZ1KGxaRA5hWQUc86mLJTiQU1EBVh3Lfb2zUq2w/gpLCoxdwiX8KnNuX1a1iC8pFCZm4VJ20yvNPaIgzFYDFfNQO6Vwv9fcLsdxVH819cEkjxg5do9MpZBj1OVmaWnTmQ4w4r3iKFzL6LMae4eOEyA/vJ8e7mbWUNrxM3+EPUPlxpG/NKr2VsR2ihIIF9GTduBZa2ayj7BJAkL9UK5PEGh/UxG6jf0YS7RjQ9ROaRgmTLMFsOVnQlFlp2UFRTe+heh/woD8/QSpd9MELdWFzeKRAlo7+hvo5AfWyjBI/3e9PIJfCXp+nF3Z92HKoR5V0m9QoYu2WGzbkhU49DJF7n+Bnd3ur0qefHFVl3USdVU2DJLcdcKU+Qn5G6E8NSy/3TVkjDg6u/o38b203b0tUBZNftAYYmCCpx/HVMEoNC03orIBPrwGYD6g//RC1TZ2ZxkLDU4QxeaM6neWq1xryXbvS4=");
public static final SkinData BARDOLF_WEREWOLF = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjkxODMxOTAsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9kNzc0ZGY3OWU1OGFiNDQ5OGQ2YzY3ZTdlMjY2NWFjZmE2OTViOWNjOWNkZTE1MmQ3ZTVlM2NjMTUyNzM5In19fQ==", "nqc7IdRVa2RF2SZXRli/HVhw7q5NfY7rnZFWbDyzjQ90Y/H6NWhb+9gwDDdnh7B1WolyptyUnukzTOQmrAcSecVO5vblhCTYY8PEOfcwUKznjpCmL/BgXdzBoYJHs43HFbtvzt3yhshcQ8Wvh7mtdmNu0MEYKbIX7lTqcfSoUbDk+A1PZDINuOF5RM8disGCrkq6WTdLij+k7pd3e7MJhtf8vJbtSoo5TjfzyzJyFvEvZqa+3lxobbPA9Z4cels0DVWVU8I/FEJhB29aSVXDVAZps3vWUr1sLMM9+PRaZdxHPZfNHx6q9R3oHXgjAlqzJwkljtJGExyOV+vOHEUuxrytdwMcW0XGjalukHVJ1A9DCgNMZqAXEbfYKk+BsN2BzOwT/+dtGfsOU+Rq7Kzp1/iit9saQy1QEG8Bynj6A2Vmg9XZsvbYsXZXsE+qNG6TOADEV0yrS9icEhLhOnO0re/+wE4Zsd5WDF51e87+ugvoH3iM4zrzvaWQb6McgxD/wlYlJyVHD+2f5VYCIw2yacNXp6LaZuXpfQyyDCqpHAosTYNLxWwjinl05C/TprQw+sZoLHFCGbVFQjTPEkDhQzG73PHecnO5Px3USBVleDoTb1kZfq6J2wJ1B1/7MTBW21Din3j2DmmuAVUNJYe6kifaNOhY1ghG2WVRNdIf1b4=");
public static final SkinData LARISSA = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjE0MTUxMzQsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jYThjNDRhOWVmZTY3NzExMDYzMjM5ODEwNDRmOTdjYmM1OWJmZmRlOGI1ODdlMGQzMWE4N2ViMDhhMmExZiJ9fX0=", "Lyac51CrnMK/CI2dWgGQLowAm/ZnQMpf0Ict/gqVrUgJVlGWDIVG77Rd1JyMQDEeESvTmoyivH+usiO0ePW95qjisqT3R43YEmLi85CqctGYqLKeSYpGYwYRz8Euw57LwJAALKOMLhVc2s4h2Or9nTecunG8KSmkCuZc4H1qh3frU+ltuV4HLqgdFUULbIHTggyvqiINov2tBqkkXeEjT7sOcTJCJNgNYU2O7//qg5kJmhso2CKHlRLpmy9LsaUK/Z+BzUmoRbwQgSwr3mz7dFAdlVWWKvKNcgX3nt1et0DIig3JKYmrnQX2Fprg+kWcr3nuizzLgjVwAlADC48P3DN0s/VBty2AYoWie16VNPIM+CV4BF2JRQ34GxZ8XceXbCKURrOjoCBgLGHvIhRW35eicoh26xp3/mwLvk5anPi5StJ/qEuzWJALeWcNbLsnt21m2MZp9h/MxaY6ftWOTzjTr5CYVd/teJyscMnGK4+lcV1dlt12lhbDMv6I+iz8iG9NIzuW5OvGkax90dA/Gq+Cd9FXVThPY4ufxWttHcTqgPB64GfMn6rywRm1B0eO1pJpYc/KlJZlW/PuaO8L1assyJs5KkOypBSy3zc6TO6pzgeOZv+VpQfA/UWpogv6ofmTpgdtwpjLFGSzIKTDXvF6FftALKVlYypG0fYbssA=");
public static final SkinData ROWENA = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0Njk1MTcxOTgsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jNDY1OGExODY4YzNhNjhhZWVhZmZkOTUxZDQyYmZkN2QxYTRjNGZjNDJjZDI2YTlmYzhkNTNmOTkxMTM1ZCJ9fX0=", "OqXMyH9SMmQ/Pwmb21In29YnCxbsN6yqUxfudN6KNgDwRUK6y072XhW6TIoTh9JQLAUKftpeVB53tk0LxHIxnsuBMrIHvETPDQFysIc/6xq3ABogs+zqFzcp5jk6S73HiD78JxLq5pzfUzhgDPMPuZP5Q/u2q1rYbe6B9lVEJ5sUcxBLUTossgucoR4qXYAlWVQdHRhq85Ol8a+OU7ruw3HackNGto6wt6u2MigCtiHVTt9XhJ/AJE4ScodQ3XwW4L6urpl/lV2OMCsr3mCjjjEz2EMhDbCWxrAorQ9aPpMbDkHBS+4TC1tbMGUlKhj5n+EZBYVaeLr4NGPACPSdT35p/2Zra49+DXn9Xn+681yNEB0ghTdsnsgwXg76+HVPHPqRHQMuTBQGQyGZaaTX/zE0tFjH+osMElLdb8dmz3dC7kQA4A13B2phj3YbMSF1FoU4GvnPKIQn6JIuEd6hd+pRLUW7Y+mgYIHHX1FT0ihrXAyVO6lQQ6rs92gSQr7sxC7tnhPSMFcmh7OcJYcbRpn97GMubthPLanOhVy7CKqjmwIkEVtYgP28idigKwNJ+sJuUONrOu7nMKl1UTD5EEapOacc/np6UhdSw8yW+LnWD/x9ueYz9ksnyRrJgcOa41izo/WCbjPK/j3JVezr9Q3x1yveWuFmdl7CGYdXngw=");
public static final SkinData BIFF = new SkinData("eyJ0aW1lc3RhbXAiOjE0OTc0NjEzMDQzNjYsInByb2ZpbGVJZCI6Ijg1MmE4YWNmNzMzNzQwZDc5OWVjYjA4ZmQ5OTY1MGI1IiwicHJvZmlsZU5hbWUiOiJLaW5nQ3JhenlfIiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9mOWMyMTE3ZDY0ZWE0ZmUxMWZiY2NhZmE2YzU5YzhlZjY3NDVkZjVkMTZjM2QwMmI4NmI2OTlmZWJjNTA0OGI1In19fQ==", "mJMpEvQ4A02z0S/chgLm5bKrrrd+zmp7A0012AB7b3KlyIHoLKEDDz+ZJgJtvN6skOqed3P+yNVqkxitugXaZZP8Af9J+/TseHn+vOy6CTK5tykRSY3Zb8Zmw1kn36v/SARAVtDIHD53yuPgJayYSAbVB7aknj1Q8XBQGUmZRMRxWWxeD7rQTOwgRYI4YJeKFf4UL9i6zxvOJuHsOAouJ7scu7VohG8vgR77Js/Z8rSu8/aSG+O9AQdzP6h9ixYNFkkQOHm7DseK/5tsWKHM4FYBgjIDKt3ApQokSbhThzGB55BA1qjXZkfCoOb13y1nOMC8WoIL6Ees1qzxG3VloGx2WAZLh+Q+/irwrFDMxk1zeU5fIRuj1c/UIM2HKdxxWgoRdrZ8ww/Jrll6maiOBx7geMn/0aOUbJ2U7gkTif6RG6YNS5YN9ZQDLh72l/akJMxF3SlmuAPmLs2kBghQ6eD2YQKuxWR/Hf1yS1YXtogFVNsGnzC1nda7F48EGL3zI+kCajbDlAGQ32aRt0btbEQ+Gj575kir3Aa53qiZ0YOIYQlhgZdOsTN2NE2s8uuy/15Rgc6K3ydgEmSZfdqyMyW0Dy7pE5TfVL8DumKRVRXdOceT5WfnW7MyqSmdorP5ab1fw2wLOnAVzhJmW8oXXNSs77WJ1/PURclxOWB4IF8=");
// Comments this out for now, so it doesn't load the player profile
// A better way to do this would check for the properties when getting the skull or the skin
// Might change on the next version

View File

@ -258,11 +258,9 @@ public class UtilParticle
}
}
PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles(particleType.particle, displayFar,
return new PacketPlayOutWorldParticles(particleType.particle, displayFar,
(float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed,
count, details);
return packet;
}
public static void PlayParticle(ParticleType type, Location location, float offsetX, float offsetY,

View File

@ -31,10 +31,16 @@ public class LineParticle
private double _maxRange;
private Set<Material> _ignoredTypes;
private boolean _ignoreAllBlocks;
private ParticleType _particleType;
private Player[] _toDisplay;
public LineParticle(Location start, Vector direction, double incrementedRange, double maxRange, ParticleType particleType, Player... toDisplay)
{
this(start, null, direction, incrementedRange, maxRange, null, particleType, toDisplay);
}
public LineParticle(Location start, Vector direction, double incrementedRange, double maxRange, Set<Material> ignoredTypes, ParticleType particleType, Player... toDisplay)
{
this(start, null, direction, incrementedRange, maxRange, ignoredTypes, particleType, toDisplay);
@ -73,7 +79,7 @@ public class LineParticle
Location newTarget = _start.clone().add(new Vector(0, 0.2, 0)).add(_direction.clone().multiply(_curRange));
_lastLocation = newTarget;
if (!(UtilBlock.airFoliage(newTarget.getBlock()) || UtilBlock.airFoliage(newTarget.getBlock().getRelative(BlockFace.UP))))
if (!_ignoreAllBlocks && (!(UtilBlock.airFoliage(newTarget.getBlock()) || UtilBlock.airFoliage(newTarget.getBlock().getRelative(BlockFace.UP)))))
{
if (_ignoredTypes == null || !_ignoredTypes.contains(newTarget.getBlock().getType()))
{
@ -87,7 +93,12 @@ public class LineParticle
return done;
}
public void setIgnoreAllBlocks(boolean b)
{
_ignoreAllBlocks = b;
}
public Location getLastLocation()
{
return _lastLocation;

View File

@ -32,6 +32,11 @@
<artifactId>mineplex-serverdata</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mineplex-questmanager</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>

View File

@ -31,6 +31,7 @@ import com.google.common.collect.Sets;
import com.google.gson.Gson;
import mineplex.cache.player.PlayerCache;
import mineplex.cache.player.PlayerInfo;
import mineplex.core.MiniPlugin;
import mineplex.core.account.command.TestRank;
import mineplex.core.account.command.UpdateRank;
@ -260,6 +261,53 @@ public class CoreClientManager extends MiniPlugin
loadClientByName(playerName, client -> runnable.run());
}
public void loadClientByUUID(UUID uuid, Consumer<CoreClient> loadedClient)
{
runAsync(() ->
{
AtomicReference<CoreClient> loaded = new AtomicReference<>();
try
{
Gson gson = new Gson();
String response = _repository.getClientByUUID(uuid);
ClientToken token = gson.fromJson(response, ClientToken.class);
if (token.Name == null || token.Rank == null)
{
loaded.set(null);
return;
}
CoreClient client = Add(token.Name, uuid);
client.SetRank(Rank.valueOf(token.Rank), false);
client.setAccountId(_repository.login(_loginProcessors, uuid, client.getName()));
Bukkit.getServer().getPluginManager().callEvent(new ClientWebResponseEvent(response, uuid));
if (client.getAccountId() > 0)
{
PlayerInfo playerInfo = PlayerCache.getInstance().getPlayer(uuid);
if (playerInfo != null)
{
PlayerCache.getInstance().updateAccountId(uuid, client.getAccountId());
}
}
loaded.set(client);
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
UtilTasks.onMainThread(() -> loadedClient.accept(loaded.get())).run();
}
});
}
public void loadClientByName(String playerName, Consumer<CoreClient> loadedClient)
{
runAsync(() ->

View File

@ -1201,7 +1201,31 @@ public enum Achievement
new String[]{"Skyfall.SupplyDropsOpened"},
new String[]{"Be the first to open 20 Supply Drops"},
new int[]{20},
AchievementCategory.SKYFALL);
AchievementCategory.SKYFALL),
GEM_HUNTERS_KILLS("Gem Killer", 5000,
new String[]{"Gem Hunters.Kills"},
new String[]{"+1 for each kill"},
new int[]{10,25,50,100,1000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_GEMS_EARNED("Gem Millionaire", 5000,
new String[]{"Gem Hunters.GemsEarned"},
new String[]{"+1 for each Gem cashed out"},
new int[]{1000,2500,5000,10000,100000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_QUESTS("Quest Complete", 5000,
new String[]{"Gem Hunters.QuestsCompleted"},
new String[]{"+1 for each quest completed"},
new int[]{10,25,50,100,1000},
AchievementCategory.GEM_HUNTERS),
GEM_HUNTERS_CHESTS_OPENED("Loot Get!", 5000,
new String[]{"Gem Hunters.ChestsOpened"},
new String[]{"+1 for each chest opened"},
new int[]{50,100,200,400,1000},
AchievementCategory.GEM_HUNTERS);
private String _name;
private String[] _desc;

View File

@ -213,7 +213,15 @@ public enum AchievementCategory
StatDisplay.fromGame("Wins", GameDisplay.SkyfallTeams, "Wins"), StatDisplay.fromGame("Games Played", GameDisplay.SkyfallTeams, "Wins", "Losses"),
StatDisplay.fromGame("Kills", GameDisplay.SkyfallTeams, "Kills"), StatDisplay.fromGame("Deaths", GameDisplay.SkyfallTeams, "Deaths"),
StatDisplay.fromGame("Gems Earned", GameDisplay.SkyfallTeams, "GemsEarned"), null, StatDisplay.fromGame("Booster Rings", GameDisplay.SkyfallTeams, "Rings")},
Material.DIAMOND_BOOTS, 0, GameCategory.SURVIVAL, null, false, GameDisplay.Skyfall.getGameId(), GameDisplay.SkyfallTeams.getGameId());
Material.DIAMOND_BOOTS, 0, GameCategory.SURVIVAL, null, false, GameDisplay.Skyfall.getGameId(), GameDisplay.SkyfallTeams.getGameId()),
GEM_HUNTERS("Gem Hunters", null,
new StatDisplay[] {StatDisplay.KILLS, StatDisplay.GEMS_EARNED, StatDisplay.fromGame("Quests Completed", GameDisplay.GemHunters, "QuestsCompleted"), StatDisplay.fromGame("Chests Opened", GameDisplay.GemHunters, "ChestsOpened")},
Material.EMERALD, 0, GameCategory.SURVIVAL, null, false, GameDisplay.GemHunters.getGameId()),
MOBA("Heroes of GWEN", null,
new StatDisplay[] {StatDisplay.WINS, StatDisplay.GAMES_PLAYED, StatDisplay.GEMS_EARNED, null, StatDisplay.fromGame("Gold Earned", GameDisplay.MOBA, "GoldEarned")},
Material.PRISMARINE_SHARD, 0, GameCategory.CLASSICS, null, false, GameDisplay.MOBA.getGameId());
private String _name;
private String[] _statsToPull;

View File

@ -51,7 +51,7 @@ public class AchievementMainPage extends ShopPageBase<AchievementManager, Achiev
protected void buildPage()
{
ArrayList<Integer> pageLayout = new ItemLayout(
"XXOXOXOXO",
"OXOXOXOXO",
"OXOXOXOXO",
"OXOXOXOXO",
"OXOXOXOXO",

View File

@ -55,8 +55,8 @@ public class BetaWhitelist extends MiniPlugin
{
Player player = event.getPlayer();
Rank rank = _clientManager.Get(player).GetRank(true);
if ((rank != Rank.MAPDEV && rank != Rank.MAPLEAD && rank.has(Rank.ETERNAL) // If this player is Eternal+ (and not a builder),
|| _powerPlayClubRepository.getCachedData(player).isSubscribed()) // a PPC subscriber,
if (rank.has(Rank.TITAN) // If this player is Titan+
|| _powerPlayClubRepository.getCachedData(player).isSubscribed() // a PPC subscriber,
|| EXTRA_PLAYERS.contains(player.getUniqueId())) // or explicitly whitelisted,
{
return; // allow them in

View File

@ -941,12 +941,7 @@ public class BonusManager extends MiniClientPlugin<BonusClientData> implements I
if (!_enabled)
return;
Entity entity = event.getRightClicked();
if (entity.equals(_carlNpc.getEntity()))
{
updateDailyStreak(event.getPlayer());
new BonusGui(_plugin, event.getPlayer(), this, _rewardManager, _facebookManager, _youtubeManager, _thankManager, _playWireManager).openInventory();
}
attemptOpenCarlGUI(event.getPlayer(), event.getRightClicked());
}
@EventHandler
@ -957,12 +952,22 @@ public class BonusManager extends MiniClientPlugin<BonusClientData> implements I
if (event.getDamager() instanceof Player)
{
Player player = (Player) event.getDamager();
if (event.getEntity().equals(_carlNpc.getEntity()))
{
updateDailyStreak(player);
new BonusGui(_plugin, player, this, _rewardManager, _facebookManager, _youtubeManager, _thankManager, _playWireManager).openInventory();
}
attemptOpenCarlGUI((Player) event.getDamager(), event.getEntity());
}
}
private void attemptOpenCarlGUI(Player player, Entity entity)
{
if (_carlNpc == null || _carlNpc.getEntity() == null)
{
System.err.println("Carl is missing! (carlNpc=" + _carlNpc + ")");
return;
}
if (entity.equals(_carlNpc.getEntity()))
{
updateDailyStreak(player);
new BonusGui(_plugin, player, this, _rewardManager, _facebookManager, _youtubeManager, _thankManager, _playWireManager).openInventory();
}
}
@ -1261,4 +1266,9 @@ public class BonusManager extends MiniClientPlugin<BonusClientData> implements I
{
_carlLocation = carlLocation;
}
public Npc getCarl()
{
return _carlNpc;
}
}

View File

@ -127,7 +127,7 @@ public class PowerPlayClubButton implements GuiItem
itemName = C.cRedB + "Power Play Club";
lore.add(C.cYellow + YearMonth.now().getMonth().getDisplayName(TextStyle.FULL, Locale.US) + "'s Cosmetic");
lore.add(C.cWhite + " " + PowerPlayClubRewards.rewards().get(YearMonth.now()).getPrizeName());
lore.add(C.cWhite + " " + PowerPlayClubRewards.getReward(YearMonth.now()).getPrizeName());
lore.add(" ");
lore.addAll(buildOtherRewardsLore(1));
lore.add(C.cRed + "Get Power Play Club months at");

View File

@ -1,57 +0,0 @@
package mineplex.core.brawl.fountain;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
/**
* This class handled filling a vertical area with a specific block based off a percent
*
* @author Shaun Bennett
*/
public class BlockProgressBar
{
// Starting block for the block fill
private final Block _startBlock;
// Direction the blockfill takes place in
private final BlockFace _direction;
// Blocks in order from lowest to highes
private final Block[] _blocks;
// Material used to fill the blocks
private final Material _material;
public BlockProgressBar(Block startBlock, Material material, BlockFace direction)
{
_startBlock = startBlock;
_material = material;
_direction = direction;
// Add blocks to array
int i;
Block curr;
Block[] blocks = new Block[100]; // max of 100 to prevent blocking
for (i = 0, curr = startBlock; (curr.getType() == Material.AIR || curr.getType() == material) && i < blocks.length; i++)
{
blocks[i] = curr;
curr = curr.getRelative(direction);
}
_blocks = new Block[i];
System.arraycopy(blocks, 0, _blocks, 0, i);
}
// Update the blockfill based on fill percent
public void update(double percent)
{
double percentPerBlock = 1D / _blocks.length;
double check = 0;
for (int i = 0; i < _blocks.length; i++)
{
_blocks[i].setType(percent > check ? _material : Material.AIR);
check += percentPerBlock;
}
}
}

View File

@ -1,11 +0,0 @@
package mineplex.core.brawl.fountain;
import mineplex.core.shop.ShopBase;
/**
* @author Shaun Bennett
*/
public interface BrawlShopProvider
{
public ShopBase getBrawlShop();
}

View File

@ -1,258 +0,0 @@
package mineplex.core.brawl.fountain;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.gui.FountainShop;
import mineplex.core.common.SortedSchematicLoader;
import mineplex.core.common.block.schematic.UtilSchematic;
import mineplex.core.common.util.C;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilText;
import mineplex.core.donation.DonationManager;
import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
import mineplex.core.stats.StatsManager;
import mineplex.serverdata.Region;
import mineplex.serverdata.redis.counter.GoalCounter;
import mineplex.serverdata.redis.counter.GoalCounterListener;
import mineplex.serverdata.servers.ConnectionData;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.TimeZone;
/**
* Represents a fountain that players can add gems to, with a reward for reaching specific goals
* @author Shaun Bennett
*/
public class Fountain implements GoalCounterListener
{
// Manager Injections
private final HologramManager _hologramManager;
private final StatsManager _statsManager;
private boolean _brawlActive;
private final String _name;
private final String _dataKey;
private final Location _location;
private final Hologram _hologram;
private final GoalCounter _counter;
// private final BlockProgressBar _blockProgressBar;
private final SortedSchematicLoader<Double> _schematicLoader;
private final FountainShop _shop;
public Fountain(ConnectionData writeConnection, ConnectionData readConnection, Region region, Location location, Location pasteLocation, String name, String dataKey, long goal, FountainManager fountainManager,
CoreClientManager clientManager, DonationManager donationManager, HologramManager hologramManager,
StatsManager statsManager)
{
_hologramManager = hologramManager;
_statsManager = statsManager;
_name = name;
_dataKey = dataKey;
_location = location;
_hologram = new Hologram(hologramManager, new Location(location.getWorld(), -23, 75, 3), name).start();
_counter = new GoalCounter(writeConnection, readConnection, region, dataKey, goal);
_counter.addListener(this);
_brawlActive = false;
// _blockProgressBar = new BlockProgressBar(_lavaLocation.getBlock(), Material.LAVA, BlockFace.UP);
_schematicLoader = new SortedSchematicLoader<>(pasteLocation);
loadSchematics();
_shop = new FountainShop(this, fountainManager, clientManager, donationManager);
updateVisuals();
}
private void loadSchematics()
{
try
{
_schematicLoader.addSchematic(0.0, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain0.schematic")));
_schematicLoader.addSchematic(0.2, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain20.schematic")));
_schematicLoader.addSchematic(0.4, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain40.schematic")));
_schematicLoader.addSchematic(0.6, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain60.schematic")));
_schematicLoader.addSchematic(0.8, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain80.schematic")));
_schematicLoader.addSchematic(1.0, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain100.schematic")));
_schematicLoader.addSchematic(2.0, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain200.schematic")));
_schematicLoader.addSchematic(3.0, UtilSchematic.loadSchematic(new File("../../update/schematic/fountain300.schematic")));
}
catch (IOException e)
{
System.err.println("Failed to load Gem Fountain Schematics");
e.printStackTrace();
}
}
protected void updateVisuals()
{
double fillPercent = getFillPercent();
if (isBrawlActive())
{
ArrayList<String> text = new ArrayList<>();
if (fillPercent >= 1)
{
text.add(C.cRed + C.Bold + "Weekend Brawl is Active!");
if (fillPercent >= 2)
{
text.add("Bonus Reward Unlocked:");
if (fillPercent >= 3)
{
text.add(C.cGreen + "3X Experience in Brawl");
}
else
{
text.add(C.cGreen + "2X Experience in Brawl");
}
}
text.add(" ");
text.add("Speak to the Fountain Keeper to Join!");
}
else
{
text.add(C.cRed + "Brawl goal was not met");
text.add("Come back next week");
}
_hologram.setText(text.toArray(new String[text.size()]));
//_schematicLoader.update(fillPercent);
}
else
{
double flatPercent = fillPercent - (int) fillPercent;
String fillColor;
String emptyColor;
String goalMessage;
if (fillPercent < 1)
{
fillColor = C.cGreen;
emptyColor = C.cRed;
goalMessage = "100% to Unlock Weekend Brawl";
} else if (fillPercent < 2)
{
fillColor = C.cYellow;
emptyColor = C.cGreen;
goalMessage = "200% to Unlock 2x XP for Weekend Brawl";
} else if (fillPercent < 3)
{
fillColor = C.cAqua;
emptyColor = C.cYellow;
goalMessage = "300% to Unlock 3x XP for Weekend Brawl";
} else
{
fillColor = C.cAqua;
emptyColor = C.cYellow;
goalMessage = "All Rewards Unlocked!";
flatPercent = 1;
}
int intPercent = (int) (fillPercent * 100);
String progressBar = UtilText.getProgress(null, flatPercent, null, false, 30, emptyColor, fillColor);
_hologram.setText(_name + C.Reset + " " + intPercent + "%", goalMessage, progressBar);
_schematicLoader.update(fillPercent);
}
}
public void increment(Player player, long amount, Callback<Long> callback)
{
_statsManager.incrementStat(player, getStatName(), amount);
_statsManager.runAsync(() -> {
long count = _counter.addAndGet(amount);
_statsManager.runSync(() -> {
updateVisuals();
if (callback != null) callback.run(count);
});
});
}
public long getAmountAdded(Player player)
{
return _statsManager.Get(player).getStat(getStatName());
}
private final String getStatName()
{
return "Global.Fountain." + getDataKey();
}
public String getName()
{
return _name;
}
public String getDataKey()
{
return _dataKey;
}
public void openShop(Player player)
{
_shop.attemptShopOpen(player);
}
public double getFillPercent()
{
return Math.min(3, _counter.getFillPercent());
}
public long getCount()
{
return _counter.getCount();
}
public void reset()
{
_counter.reset();
updateVisuals();
}
@Override
public void onMilestone(GoalCounter counter, int milestone)
{
switch (milestone)
{
case 1:
Bukkit.broadcastMessage(F.main("Fountain", "The Gem Fountain has reached 100%! Brawl Game unlocked this week"));
break;
case 2:
Bukkit.broadcastMessage(F.main("Fountain", "The Gem Fountain has reached 200%! 2x XP enabled for Brawl!"));
break;
case 3:
Bukkit.broadcastMessage(F.main("Fountain", "The Gem Fountain has reached 300%! 3x XP enabled for Brawl!"));
break;
}
}
public void updateBrawlActive()
{
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("PST"));
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == Calendar.FRIDAY || dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY)
{
_brawlActive = true;
}
else
{
_brawlActive = false;
}
}
public void updateCounter()
{
_counter.updateCount();
}
public boolean isBrawlActive()
{
return _brawlActive;
}
}

View File

@ -1,123 +0,0 @@
package mineplex.core.brawl.fountain;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.command.FountainCommand;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.hologram.HologramManager;
import mineplex.core.locations.LocationConstants;
import mineplex.core.stats.StatsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.Region;
import mineplex.serverdata.servers.ConnectionData;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.plugin.java.JavaPlugin;
/**
* @author Shaun Bennett
*/
public class FountainManager extends MiniPlugin
{
private HologramManager _hologramManager;
private StatsManager _statsManager;
private DonationManager _donationManager;
// used so we can inject the brawl shop (only on hub) into fountain code
private BrawlShopProvider _brawlShopProvider;
private Fountain _gemFountain;
public FountainManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, HologramManager hologramManager, StatsManager statsManager, BrawlShopProvider shopProvider)
{
super("Counter", plugin);
_hologramManager = hologramManager;
_statsManager = statsManager;
_donationManager = donationManager;
_brawlShopProvider = shopProvider;
World world = Bukkit.getWorlds().get(0);//-43.5, 66, -38.5
int goal = 35000000;//!new File("eu.dat").exists() ? 200000000 : 20000000;
_gemFountain = new Fountain(new ConnectionData("10.3.203.80", 6379, ConnectionData.ConnectionType.MASTER, "USRedis"),
new ConnectionData("10.3.203.80", 6377, ConnectionData.ConnectionType.SLAVE, "USRedis"), Region.ALL,
LocationConstants.FOUNTAIN_LOCATION, LocationConstants.FOUNTAIN_SCHEMATIC,
C.cGreen + "Gem Fountain", "GemFountain_01", goal, this, clientManager, donationManager, _hologramManager, _statsManager);
}
@Override
public void addCommands()
{
addCommand(new FountainCommand(this));
}
@EventHandler
public void updateFountainCount(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
return;
_gemFountain.updateBrawlActive();
_gemFountain.updateVisuals();
}
@EventHandler
public void updateCounter(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC_05)
return;
runAsync(_gemFountain::updateCounter);
}
@EventHandler
public void onInteractAtEntity(PlayerInteractAtEntityEvent event)
{
Entity entity = event.getRightClicked();
if (entity.getCustomName() != null && entity.isCustomNameVisible())
{
if (entity.getCustomName().contains("Weekend Brawl") && getBrawlShopProvider() != null)
{
getBrawlShopProvider().getBrawlShop().attemptShopOpen(event.getPlayer());
}
}
}
@EventHandler
public void onDamage(EntityDamageByEntityEvent event)
{
if (!(event.getDamager() instanceof Player))
return;
Entity entity = event.getEntity();
if (entity.getCustomName() != null && entity.isCustomNameVisible())
{
if (entity.getCustomName().contains("Weekend Brawl") && getBrawlShopProvider() != null)
{
getBrawlShopProvider().getBrawlShop().attemptShopOpen(((Player) event.getDamager()));
}
}
}
public Fountain getGemFountain()
{
return _gemFountain;
}
public DonationManager getDonationManager()
{
return _donationManager;
}
public BrawlShopProvider getBrawlShopProvider()
{
return _brawlShopProvider;
}
}

View File

@ -1,20 +0,0 @@
package mineplex.core.brawl.fountain;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.shop.item.SalesPackageBase;
import org.bukkit.Material;
/**
* @author Shaun Bennett
*/
public class GemFountainSalesPackage extends SalesPackageBase
{
public GemFountainSalesPackage(int gems)
{
super("Add " + gems + " Gems", Material.EMERALD, (byte) 0, new String[] {}, gems, 1);
CurrencyCostMap.put(GlobalCurrency.GEM, gems);
KnownPackage = false;
OneTimePurchaseOnly = false;
}
}

View File

@ -1,69 +0,0 @@
package mineplex.core.brawl.fountain.command;
import java.util.function.Consumer;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.server.util.TransactionResponse;
import org.bukkit.entity.Player;
/**
* Command to add gems to the fountain
*
* @author Shaun Bennett
*/
public class AddCommand extends CommandBase<FountainManager>
{
public AddCommand(FountainManager plugin)
{
super(plugin, Rank.DEVELOPER, "add");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args == null || args.length != 1)
{
help(caller);
return;
}
try
{
int amount = Integer.parseInt(args[0]);
Plugin.getDonationManager().purchaseUnknownSalesPackage(caller, "GemFountain.Add", GlobalCurrency.GEM, amount, false,
result ->
{
if (result == TransactionResponse.Success)
{
Plugin.getGemFountain().increment(caller, amount, null);
UtilPlayer.message(caller, F.main("Fountain", "Added " + F.elem(amount) + " to the fountain!"));
}
else if (result == TransactionResponse.InsufficientFunds)
{
UtilPlayer.message(caller, F.main("Fountain", "You do not have enough gems!"));
}
else
{
UtilPlayer.message(caller, F.main("Fountain", "There was an error processing your request!"));
}
});
}
catch (NumberFormatException ex)
{
help(caller);
}
}
private void help(Player player)
{
UtilPlayer.message(player, F.help("/fountain add", "<amount>", Rank.DEVELOPER));
}
}

View File

@ -1,27 +0,0 @@
package mineplex.core.brawl.fountain.command;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.command.MultiCommandBase;
import mineplex.core.common.Rank;
import org.bukkit.entity.Player;
/**
* @author Shaun Bennett
*/
public class FountainCommand extends MultiCommandBase<FountainManager>
{
public FountainCommand(FountainManager plugin)
{
super(plugin, Rank.DEVELOPER, "fountain");
AddCommand(new AddCommand(plugin));
AddCommand(new GuiCommand(plugin));
AddCommand(new ResetCommand(plugin));
}
@Override
protected void Help(Player caller, String[] args)
{
}
}

View File

@ -1,26 +0,0 @@
package mineplex.core.brawl.fountain.command;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import org.bukkit.entity.Player;
/**
* Command to open the fountain gui without speaking to the fountain keeper
* @author Shaun Bennett
*/
public class GuiCommand extends CommandBase<FountainManager>
{
public GuiCommand(FountainManager plugin)
{
super(plugin, Rank.DEVELOPER, "gui");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.getGemFountain().openShop(caller);
}
}

View File

@ -1,26 +0,0 @@
package mineplex.core.brawl.fountain.command;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import org.bukkit.entity.Player;
/**
* Command to reset the fountain
* @author Shaun Bennett
*/
public class ResetCommand extends CommandBase<FountainManager>
{
public ResetCommand(FountainManager plugin)
{
super(plugin, Rank.DEVELOPER, "reset");
}
@Override
public void Execute(Player caller, String[] args)
{
Plugin.getGemFountain().reset();
}
}

View File

@ -1,92 +0,0 @@
package mineplex.core.brawl.fountain.gui;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.Fountain;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.brawl.fountain.gui.button.FountainAddButton;
import mineplex.core.common.MaterialData;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.item.ShopItem;
import mineplex.core.shop.page.ShopPageBase;
import org.bukkit.Material;
import org.bukkit.entity.Player;
/**
* @author Shaun Bennett
*/
public class FountainPage extends ShopPageBase<FountainManager, FountainShop>
{
private final MaterialData EMPTY_XP = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 7);
private final MaterialData XP = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 5);
private final MaterialData EMPTY_XP100 = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 5);
private final MaterialData XP100 = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 4);
private final MaterialData EMPTY_XP200 = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 4);
private final MaterialData XP200 = MaterialData.of(Material.STAINED_GLASS_PANE, (byte) 3);
private final int[] XP_SLOTS = { 2, 3, 4, 5, 6 };
private Fountain _fountain;
public FountainPage(FountainManager plugin, FountainShop shop, CoreClientManager clientManager, DonationManager donationManager, Fountain fountain, Player player)
{
super(plugin, shop, clientManager, donationManager, "Fountain Keeper", player, 27);
_fountain = fountain;
buildPage();
}
@Override
protected void buildPage()
{
// Experience Bar
long added = _fountain.getAmountAdded(getPlayer());
final double fillPercent = _fountain.getFillPercent();
String title = ((int)(fillPercent * 100)) + "% Complete";
boolean canAdd = fillPercent < 3;
String unlockMessage;
if (fillPercent < 1) unlockMessage = "Reach 100% to unlock Weekend Brawl Game";
else if (fillPercent < 2) unlockMessage = "Reach 200% to unlock 2x XP in Brawl";
else if (fillPercent < 3) unlockMessage = "Reach 300% to unlock 3x XP in Brawl";
else unlockMessage = "All rewards unlocked!";
String[] lore = new String[] {
" ",
C.cWhite + unlockMessage,
" ",
C.cWhite + "You have added " + C.cGreen + added + " Gems"};
final double percentForEach = 1D / XP_SLOTS.length;
double check = percentForEach;
double flatPercent = fillPercent == 3 ? 1 : fillPercent - ((int) fillPercent);
for (int i = 0; i < XP_SLOTS.length; i++)
{
MaterialData data;
if (fillPercent < 1) data = flatPercent >= check ? XP : EMPTY_XP;
else if (fillPercent < 2) data = flatPercent >= check ? XP100 : EMPTY_XP100;
else data = flatPercent >= check ? XP200 : EMPTY_XP200;
ShopItem shopItem = new ShopItem(data.getMaterial(), data.getData(), title,
lore, 1, false, false);
setItem(XP_SLOTS[i], shopItem);
check += percentForEach;
}
if (canAdd)
{
int playerGems = getDonationManager().Get(getPlayer()).getBalance(GlobalCurrency.GEM);
ShopItem add1 = new ShopItem(Material.EMERALD, "Add 100 Gems", new String[]{}, 1, playerGems < 100, false);
ShopItem add2 = new ShopItem(Material.EMERALD, "Add 1,000 Gems", new String[]{}, 64, playerGems < 1000, false);
ShopItem add3 = new ShopItem(Material.EMERALD_BLOCK, "Add 10,000 Gems", new String[]{}, 1, playerGems < 10000, false);
ShopItem add4 = new ShopItem(Material.EMERALD_BLOCK, "Add 100,000 Gems", new String[]{}, 64, playerGems < 100000, false);
// Buttons
addButton(19, add1, new FountainAddButton(this, 100));
addButton(21, add2, new FountainAddButton(this, 1000));
addButton(23, add3, new FountainAddButton(this, 10000));
addButton(25, add4, new FountainAddButton(this, 100000));
}
}
}

View File

@ -1,48 +0,0 @@
package mineplex.core.brawl.fountain.gui;
import mineplex.core.account.CoreClientManager;
import mineplex.core.brawl.fountain.Fountain;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
import org.bukkit.entity.Player;
/**
* @author Shaun Bennett
*/
public class FountainShop extends ShopBase<FountainManager>
{
private final Fountain _fountain;
public FountainShop(Fountain fountain, FountainManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super(plugin, clientManager, donationManager, "Fountain Keeper");
_fountain = fountain;
}
@Override
protected ShopPageBase<FountainManager, ? extends ShopBase<FountainManager>> buildPagesFor(Player player)
{
return new FountainPage(getPlugin(), this, getClientManager(), getDonationManager(), _fountain, player);
}
public Fountain getFountain()
{
return _fountain;
}
@Override
public boolean attemptShopOpen(Player player)
{
if (_fountain.isBrawlActive() && getPlugin().getBrawlShopProvider() != null)
{
return getPlugin().getBrawlShopProvider().getBrawlShop().attemptShopOpen(player);
}
else
{
return super.attemptShopOpen(player);
}
}
}

View File

@ -1,38 +0,0 @@
package mineplex.core.brawl.fountain.gui.button;
import mineplex.core.brawl.fountain.GemFountainSalesPackage;
import mineplex.core.brawl.fountain.gui.FountainPage;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.shop.confirmation.ConfirmationPage;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.SalesPackageBase;
import mineplex.core.shop.item.SalesPackageProcessor;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
/**
* @author Shaun Bennett
*/
public class FountainAddButton implements IButton
{
private final FountainPage _page;
private final int _gems;
private final SalesPackageBase _salesPackage;
public FountainAddButton(FountainPage page, int gems)
{
_page = page;
_gems = gems;
_salesPackage = new GemFountainSalesPackage(gems);
}
@Override
public void onClick(Player player, ClickType clickType)
{
_page.getShop().openPageForPlayer(player, new ConfirmationPage<>(player, _page, new SalesPackageProcessor(player, GlobalCurrency.GEM, _salesPackage, _page.getDonationManager(), () ->
{
_page.getPlugin().getGemFountain().increment(player, _gems, null);
_page.refresh();
}), _salesPackage.buildIcon()));
}
}

View File

@ -33,7 +33,7 @@ public class FallingBlocks extends MiniPlugin
if (vec.getY() < 0)
{
vec.setY(vec.getY() * -1);
vec.setY(-vec.getY());
}
Spawn(location, type, data, vec);
@ -46,7 +46,6 @@ public class FallingBlocks extends MiniPlugin
UtilAction.velocity(fall, velocity, 0.5 + 0.25 * Math.random(), false, 0, 0.4 + 0.20 * Math.random(), 10, false);
fall.setMetadata(METADATA, new FixedMetadataValue(_plugin, "x"));
UtilEnt.SetMetadata(fall, METADATA, "x");
}

View File

@ -5,11 +5,9 @@ import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import mineplex.core.common.util.C;
import mineplex.core.common.util.LineFormat;
@ -21,12 +19,16 @@ import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.recharge.Recharge;
import mineplex.core.treasure.event.TreasureFinishEvent;
import mineplex.core.treasure.event.TreasureStartEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
@ -48,17 +50,14 @@ import mineplex.core.utils.UtilGameProfile;
*/
public class MorphBobRoss extends MorphGadget
{
/** Radius within which painting is not allowed near treasure chests */
private static final int TREASURE_RADIUS = 4;
/** The inventory slot in which the paint brush is placed */
private static final int PAINT_BRUSH_SLOT = 2;
/** Max # of blocks that can be destroyed every quarter second, per player */
private static final int DESTROY_LIMIT = 4;
/** The # of seconds for which paint blocks exist */
private static final int PAINT_SECONDS = 30;
/** The # of minutes after which the code will stop trying to remove paint */
private static final int PAINT_EXPIRE = 10;
/** The # of milliseconds for which paint blocks exist */
private static final long PAINT_MILLISECONDS = 30000;
/** Height above a player's location at which quotes are to be displayed */
private static final double QUOTE_HEIGHT = 2.25;
@ -196,10 +195,11 @@ public class MorphBobRoss extends MorphGadget
/** Map of items in players' inventories */
private final Map<UUID, ItemStack> _inventoryItems = new HashMap<>();
private final Map<UUID, Integer> _paintColors = new HashMap<>();
/** Colors that are being used by painting players */
private final Map<UUID, Byte> _paintColors = new HashMap<>();
/** Blocks that have been painted */
private final List<PaintedBlock> _paintBlocks = new ArrayList<>();
/** Locations at which treasure is currently being opened */
private final Map<UUID, Location> _openingTreasure = new HashMap<>();
private final HologramManager _holograms;
@ -277,6 +277,7 @@ public class MorphBobRoss extends MorphGadget
{
if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{
changePaintColor(event.getPlayer(), true);
}
}
@ -284,6 +285,7 @@ public class MorphBobRoss extends MorphGadget
{
if (Recharge.Instance.use(event.getPlayer(), COLOR_KEY, COLOR_COOLDOWN, false, false))
{
changePaintColor(event.getPlayer(), false);
}
}
@ -296,40 +298,7 @@ public class MorphBobRoss extends MorphGadget
@EventHandler
public void updateEvent(UpdateEvent event)
{
if (event.getType() == UpdateType.FASTER) // do paint removal
{
int limit = 0;
int offset = 0;
// destroy paint blocks that are too old
while (!_paintBlocks.isEmpty()
&& offset < _paintBlocks.size()
&& _paintBlocks.get(offset).time < System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(PAINT_SECONDS)
&& limit < DESTROY_LIMIT * getActive().size())
{
Block block = _paintBlocks.get(offset).block;
if (block.getType() == Material.CARPET)
{
_paintBlocks.remove(offset);
block.setType(Material.AIR);
limit++;
}
else
{
// stop trying to remove paint after a certain amount of time
if (_paintBlocks.get(offset).time > System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(PAINT_EXPIRE))
{
_paintBlocks.remove(offset);
}
else
{
offset++;
}
}
}
}
else if (event.getType() == UpdateType.TICK) // do quote displaying
if (event.getType() == UpdateType.TICK) // do quote displaying
{
for (Player player : getActive())
{
@ -377,10 +346,12 @@ public class MorphBobRoss extends MorphGadget
if (item.getType() == Material.STICK && player.getItemInHand().equals(item))
{
togglePainting(player);
}
else if (!player.getItemInHand().equals(item) && item.getType() != Material.STICK)
{
togglePainting(player);
}
}
@ -401,6 +372,14 @@ public class MorphBobRoss extends MorphGadget
return;
}
for (Location location : _openingTreasure.values())
{
if (location.toVector().isInSphere(event.getPlayer().getLocation().toVector(), TREASURE_RADIUS))
{
return;
}
}
// check if the player has been issued a paintbrush
if (_inventoryItems.containsKey(player.getUniqueId()))
{
@ -419,28 +398,15 @@ public class MorphBobRoss extends MorphGadget
// check that there is room to paint and that the block below is solid and not more paint.
if ((block.isEmpty() || carpet) && UtilBlock.fullSolid(down) && !UtilBlock.bottomSlab(down))
{
int index;
PaintedBlock blk = new PaintedBlock(block);
if (carpet) // if block is a carpet
// if the block is a non-paint carpet
if (carpet && !Manager.getBlockRestore().contains(block))
{
// remove old paint if it was painted
if ((index = _paintBlocks.indexOf(blk)) != -1)
{
_paintBlocks.remove(index);
}
else // if it's non-paint carpet
{
return; // don't paint
}
return; // don't paint
}
// mark block as painted
_paintBlocks.add(blk);
// actually paint block
block.setType(Material.CARPET);
block.setData((byte) (15 - item.getData().getData()));
Manager.getBlockRestore().add(block, Material.CARPET.getId(), (byte) (15 - item.getData().getData()),
block.getTypeId(), block.getData(), PAINT_MILLISECONDS);
}
}
}
@ -456,6 +422,7 @@ public class MorphBobRoss extends MorphGadget
UUID uuid = event.getPlayer().getUniqueId();
_inventoryItems.remove(uuid);
_paintColors.remove(uuid);
}
}
@ -466,6 +433,7 @@ public class MorphBobRoss extends MorphGadget
*/
private void changePaintColor(Player player, boolean reverse)
{
ItemStack item = _inventoryItems.remove(player.getUniqueId());
byte data = selectPaintColor(player, reverse);
@ -483,22 +451,27 @@ public class MorphBobRoss extends MorphGadget
*/
private void togglePainting(Player player)
{
ItemStack item = _inventoryItems.remove(player.getUniqueId());
ItemStack newItem;
if (item.getType() == Material.STICK)
{
byte data = selectPaintColor(player, false);
byte data;
if (!_paintColors.containsKey(player.getUniqueId()))
{
data = selectPaintColor(player, false);
}
else
{
data = COLOR_ORDER[_paintColors.get(player.getUniqueId())];
}
newItem = ItemStackFactory.Instance.CreateStack(Material.INK_SACK, data, 1,
PAINT_COLORS[data] + " " + PAINT_BRUSHES[ThreadLocalRandom.current().nextInt(0, PAINT_BRUSHES.length)]);
}
else
{
if (_paintColors.containsKey(player.getUniqueId()))
{
_paintColors.remove(player.getUniqueId());
}
newItem = ItemStackFactory.Instance.CreateStack(Material.STICK, (byte) 0, 1, BRUSH_NAME);
}
@ -521,11 +494,11 @@ public class MorphBobRoss extends MorphGadget
{
UUID uuid = player.getUniqueId();
int value;
byte value;
if (!_paintColors.containsKey(uuid))
{
value = ThreadLocalRandom.current().nextInt(0, 16);
value = (byte) ThreadLocalRandom.current().nextInt(0, 16);
_paintColors.put(uuid, value);
}
else
@ -588,43 +561,24 @@ public class MorphBobRoss extends MorphGadget
}
/**
* Data class holding information on blocks which have been painted
* Disable painting in the area around treasure being opened.
*/
private class PaintedBlock
@EventHandler(priority = EventPriority.LOW)
public void disableOnTreasureStart(TreasureStartEvent event)
{
/** The time at which the block was painted */
long time;
_openingTreasure.put(event.getPlayer().getUniqueId(), event.getPlayer().getLocation());
Manager.getBlockRestore().restoreBlockAround(Material.CARPET, event.getPlayer().getLocation(), TREASURE_RADIUS);
}
/** The block which was painted */
Block block;
/**
* Construct a PaintedBlock
*
* @param block The block which has been painted.
*/
public PaintedBlock(Block block)
/**
* Enable painting in the area around treasure no longer being opened.
*/
@EventHandler(priority = EventPriority.HIGH)
public void enableOnTreasureFinish(TreasureFinishEvent event)
{
if (_openingTreasure.containsKey(event.getPlayer().getUniqueId()))
{
this.block = block;
this.time = System.currentTimeMillis();
}
/**
* Overrides default equals behavior to have comparisons between
* multiple {@link PaintedBlock} objects match comparisons between
* their contained {@link PaintedBlock#block} fields.
*/
@Override
public boolean equals(Object o)
{
if (o instanceof PaintedBlock)
{
return block.equals(((PaintedBlock) o).block);
}
else
{
return super.equals(o);
}
_openingTreasure.remove(event.getPlayer().getUniqueId());
}
}
}

View File

@ -20,7 +20,7 @@ public class ParticleCoalFumes extends ParticleGadget
public ParticleCoalFumes(GadgetManager manager)
{
super(manager, "Coal Fumes",
UtilText.splitLineToArray(C.cGray + "Being on the Naughty List does have some perks... if you love coal, that is...", LineFormat.LORE),
UtilText.splitLineToArray(C.cGray + "Being on the Naughty List does have some hattori... if you love coal, that is...", LineFormat.LORE),
-1, Material.COAL, (byte) 0);
}

View File

@ -104,6 +104,10 @@ public enum GameDisplay
AlienInvasion("Alien Invasion", Material.ENDER_STONE, (byte) 0, GameCategory.EVENT, 69, false),
MOBA("Heroes of GWEN", Material.SKULL_ITEM, (byte)1, GameCategory.CLASSICS, 70, true),
GemHunters("Gem Hunters", Material.EMERALD, (byte) 0, GameCategory.SURVIVAL, 71, false),
Event("Mineplex Event", Material.CAKE, (byte)0, GameCategory.EVENT, 999, false),
Brawl("Brawl", Material.DIAMOND, (byte) 0, GameCategory.EVENT, 998, false);

View File

@ -82,16 +82,23 @@ public class SimpleGui implements ItemRefresher, Listener
{
Validate.isTrue(i >= 0 && i < _size, "Tried to add a gui item outside of inventory range");
GuiItem oldItem = getItem(i);
if (oldItem != null) oldItem.close();
if (item != null)
try
{
_items[i] = item;
item.setup();
}
GuiItem oldItem = getItem(i);
if (oldItem != null) oldItem.close();
refreshItem(i);
if (item != null)
{
_items[i] = item;
item.setup();
}
refreshItem(i);
} catch (Exception ex)
{
System.err.println("Failed to add item " + item + " to GUI " + this + ": ");
ex.printStackTrace();
}
}
public GuiItem getItem(int i)

View File

@ -1,13 +1,7 @@
package mineplex.core.itemstack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilInv;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Color;
@ -21,10 +15,18 @@ import org.bukkit.inventory.meta.BannerMeta;
import org.bukkit.inventory.meta.FireworkEffectMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.potion.PotionEffect;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilInv;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ItemBuilder
{
@ -53,14 +55,15 @@ public class ItemBuilder
private Color _color;
private short _data;
private short _durability;
private final HashMap<Enchantment, Integer> _enchants = new HashMap<Enchantment, Integer>();
private final List<String> _lore = new ArrayList<String>();
private final Map<Enchantment, Integer> _enchants = new HashMap<>();
private final List<String> _lore = new ArrayList<>();
private Material _mat;
private String _title = null;
private boolean _unbreakable;
private boolean _glow;
private String _playerHeadName = null;
private HashSet<ItemFlag> _itemFlags = new HashSet<ItemFlag>();
private Set<ItemFlag> _itemFlags = new HashSet<>();
private List<PotionEffect> _potionEffects = new ArrayList<>();
public ItemBuilder(ItemStack item)
{
@ -86,6 +89,13 @@ public class ItemBuilder
{
setColor(((LeatherArmorMeta) meta).getColor());
}
else if (meta instanceof PotionMeta)
{
for (PotionEffect effect : ((PotionMeta) meta).getCustomEffects())
{
addPotionEffect(effect);
}
}
_itemFlags.addAll(meta.getItemFlags());
@ -124,7 +134,7 @@ public class ItemBuilder
return this;
}
public HashSet<ItemFlag> getItemFlags()
public Set<ItemFlag> getItemFlags()
{
return _itemFlags;
}
@ -279,6 +289,22 @@ public class ItemBuilder
{
((BannerMeta) meta).setBaseColor(DyeColor.getByColor(_color));
}
else if (meta instanceof PotionMeta)
{
PotionMeta potionMeta = (PotionMeta) meta;
for (PotionEffect effect : _potionEffects)
{
potionMeta.addCustomEffect(effect, true);
}
if (!_potionEffects.isEmpty())
{
potionMeta.setMainEffect(_potionEffects.get(0).getType());
}
meta = potionMeta;
}
meta.addItemFlags(getItemFlags().toArray(new ItemFlag[0]));
meta.spigot().setUnbreakable(isUnbreakable());
@ -307,7 +333,7 @@ public class ItemBuilder
}
newBuilder.setColor(_color);
// newBuilder.potion = potion;
newBuilder.setDurability(_durability);
newBuilder.setData(_data);
@ -321,11 +347,16 @@ public class ItemBuilder
newBuilder.setItemFlags(_itemFlags);
newBuilder.setPlayerHead(_playerHeadName);
for (PotionEffect potionEffect : _potionEffects)
{
newBuilder.addPotionEffect(potionEffect);
}
return newBuilder;
}
public HashMap<Enchantment, Integer> getAllEnchantments()
public Map<Enchantment, Integer> getAllEnchantments()
{
return _enchants;
}
@ -452,4 +483,9 @@ public class ItemBuilder
return this;
}
public ItemBuilder addPotionEffect(PotionEffect effect)
{
_potionEffects.add(effect);
return this;
}
}

View File

@ -188,4 +188,10 @@ public class Npc
{
_location = location;
}
@Override
public String toString()
{
return "NPC[entity=" + _entity + "]";
}
}

View File

@ -104,8 +104,6 @@ public class PowerPlayClubRepository implements Listener {
PowerPlayData cached = getCachedData(player);
List<PowerPlayClubRewards.PowerPlayClubItem> list = PowerPlayClubRewards.rewardsForMonths(cached.getUsableCosmeticMonths());
PowerPlayClubRewards.rewardsForMonths(cached.getUsableCosmeticMonths()).forEach(item -> item.reward(player));
// Gives Metal Man for anyone subscribed

View File

@ -49,6 +49,15 @@ public class PowerPlayClubRewards
void reward(Player player);
}
private static final PowerPlayClubItem MISSING = new PowerPlayClubItem()
{
@Override
public String getPrizeName() { return "Coming soon!"; }
@Override
public void reward(Player player) { }
};
private static class UnknownSalesPackageItem implements PowerPlayClubItem
{
private static final DonationManager _donationManager = Managers.require(DonationManager.class);
@ -104,7 +113,7 @@ public class PowerPlayClubRewards
public static List<PowerPlayClubItem> rewardsForMonths(Set<YearMonth> months)
{
return months.stream().sorted().map(rewards::get).collect(Collectors.toList());
return months.stream().sorted().map(PowerPlayClubRewards::getReward).collect(Collectors.toList());
}
public static Map<YearMonth, PowerPlayClubItem> rewards()
@ -112,6 +121,10 @@ public class PowerPlayClubRewards
return rewards;
}
public static PowerPlayClubItem getReward(YearMonth month)
{
return rewards.getOrDefault(month, MISSING);
}
public static void giveAllItems(Player player, InventoryManager inventoryManager, PowerPlayClubRepository repo)
{

View File

@ -1,12 +1,18 @@
package mineplex.core.powerplayclub;
import com.google.common.base.Objects;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.common.base.MoreObjects;
public class PowerPlayData
{
/* If this is set, the player's subscription is planned to recur.
@ -19,6 +25,9 @@ public class PowerPlayData
*/
private final Optional<LocalDate> _nextClaimDate;
// The source set of subscriptions from which this was built
private final List<Subscription> _subscriptions;
// The months where the player hasn't claimed chests/amplifiers
private final Set<YearMonth> _unclaimedMonths;
@ -29,11 +38,11 @@ public class PowerPlayData
*/
private final Set<YearMonth> _cosmeticMonths;
static PowerPlayData fromSubsAndClaims(List<Subscription> subscriptions, List<YearMonth> claimedMonths)
public static PowerPlayData fromSubsAndClaims(List<Subscription> subscriptions, List<YearMonth> claimedMonths)
{
if (subscriptions.isEmpty())
{
return new PowerPlayData(Optional.empty(), new HashSet<>(), new HashSet<>());
return new PowerPlayData(subscriptions, Optional.empty(), new HashSet<>(), new HashSet<>());
}
final LocalDate today = LocalDate.now();
@ -96,7 +105,7 @@ public class PowerPlayData
.map(YearMonth::from)
.collect(Collectors.toSet());
return new PowerPlayData(nextClaimDate, unclaimedMonths, cosmeticMonths);
return new PowerPlayData(subscriptions, nextClaimDate, unclaimedMonths, cosmeticMonths);
}
private static List<LocalDate> buildMonths(Subscription subscription)
@ -126,10 +135,10 @@ public class PowerPlayData
}
}
static class Subscription
public static class Subscription
{
private final LocalDate _startDate;
private final SubscriptionDuration _duration;
public final LocalDate _startDate;
public final SubscriptionDuration _duration;
Subscription(LocalDate startDate, SubscriptionDuration duration)
{
@ -143,13 +152,19 @@ public class PowerPlayData
MONTH, YEAR
}
private PowerPlayData(Optional<LocalDate> nextClaimDate, Set<YearMonth> unclaimedMonths, Set<YearMonth> cosmeticMonths)
private PowerPlayData(List<Subscription> subscriptions, Optional<LocalDate> nextClaimDate, Set<YearMonth> unclaimedMonths, Set<YearMonth> cosmeticMonths)
{
_subscriptions = subscriptions;
_nextClaimDate = nextClaimDate;
_unclaimedMonths = unclaimedMonths;
_cosmeticMonths = cosmeticMonths;
}
public List<Subscription> getSubscriptions()
{
return _subscriptions;
}
public Optional<LocalDate> getNextClaimDate()
{
return _nextClaimDate;
@ -173,7 +188,7 @@ public class PowerPlayData
@Override
public String toString()
{
return Objects.toStringHelper(this)
return MoreObjects.toStringHelper(this)
.add("_nextClaimDate", _nextClaimDate)
.add("_unclaimedMonths", _unclaimedMonths)
.add("_cosmeticMonths", _cosmeticMonths)

View File

@ -0,0 +1,240 @@
package mineplex.core.quests;
import org.bukkit.ChatColor;
import mineplex.core.game.GameCategory;
import mineplex.core.game.GameDisplay;
/**
* Quest
*
* @author xXVevzZXx
*/
public class Quest
{
private static final Object _progressLock = new Object();
private int _questID;
private String _questName;
private String _questTask;
private int _questCost;
private String _questReward;
private QuestRarity _rarity;
private String _type;
private GameDisplay _game;
private GameCategory _gameCategory;
private boolean _generalGame;
private boolean _overworld;
private TriggerType _trigger;
private String[] _item;
private int _statToComplete;
private long _lastCompleted;
private int _current;
private int _timesCompleted;
public Quest(int questID, String name, String task, int cost, String reward, QuestRarity rarity, String type, TriggerType trigger, String[] item, int statToComplete)
{
_questID = questID;
_questName = name;
_questTask = task;
_questCost = cost;
_questReward = reward;
_rarity = rarity;
_trigger = trigger;
_item = item;
_statToComplete = statToComplete;
_type = type;
if (GameDisplay.matchName(type) != null)
_game = GameDisplay.matchName(type);
try
{
_gameCategory = GameCategory.valueOf(type);
}
catch (IllegalArgumentException e) {}
_generalGame = _type.equalsIgnoreCase("General");
if (!_generalGame)
_overworld = (_game == null && _gameCategory == null);
}
public int getID()
{
return _questID;
}
public String getName()
{
return _questName;
}
public String getTask()
{
return _questTask;
}
public int getCost()
{
return _questCost;
}
public String getReward()
{
return _questReward;
}
public QuestRarity getRarity()
{
return _rarity;
}
public GameDisplay getGame()
{
return _game;
}
public GameCategory getGameCategory()
{
return _gameCategory;
}
public boolean isInOverworld()
{
return _overworld;
}
public TriggerType getTrigger()
{
return _trigger;
}
public String[] getItem()
{
return _item;
}
public int getStatToComplete()
{
return _statToComplete;
}
public int getProgress()
{
return _current;
}
public void setProgress(int progress)
{
_current = progress;
}
public void increment(int value)
{
synchronized (_progressLock)
{
_current += value;
}
}
public void increment()
{
synchronized (_progressLock)
{
_current++;
}
}
public void decrement(int value)
{
synchronized (_progressLock)
{
_current -= value;
}
}
public void decrement()
{
synchronized (_progressLock)
{
_current--;
}
}
public boolean isCompleted()
{
return _current >= _statToComplete;
}
public void setLastCompleted(long time)
{
_lastCompleted = time;
}
public long getLastCompleted()
{
return _lastCompleted;
}
public String getRewardName()
{
return _questReward.split(":")[0];
}
public int getRewardAmount()
{
return Integer.parseInt(_questReward.split(":")[1]);
}
public void setTimesCompleted(int amount)
{
_timesCompleted = amount;
}
public int getTimesCompleted()
{
return _timesCompleted;
}
public boolean isActive()
{
return _current != -1;
}
public String[] getQuestInfo()
{
String[] info = new String[]{
ChatColor.LIGHT_PURPLE + getTask(), "", ChatColor.GRAY + "Reward: " + ChatColor.AQUA + getRewardAmount() + " " + getRewardName(),
"",
ChatColor.GRAY + "Progress: "
+ (_current == -1 ? ChatColor.RED + "Not in your " + QuestManager.QUEST_NAME + " Inventory" :
(isCompleted() ? ChatColor.GREEN + "Completed!" :
ChatColor.YELLOW + "" + getProgress() + ChatColor.GRAY + "/" + ChatColor.YELLOW + getStatToComplete())),
"",
getRarity().getColor() + "" + ChatColor.BOLD + getRarity().toString(),
};
return info;
}
public boolean isGeneral()
{
return _generalGame;
}
@Override
public Quest clone()
{
return new Quest(_questID, _questName, _questTask, _questCost, _questReward, _rarity, _type, _trigger, _item, _statToComplete);
}
}

View File

@ -0,0 +1,94 @@
package mineplex.core.quests;
import java.util.ArrayList;
import mineplex.core.hologram.Hologram;
/**
* QuestClientData
*
* @author xXVevzZXx
*/
public class QuestClientData
{
private ArrayList<Quest> _quests = new ArrayList<>();
private Hologram _hologram;
public void addQuest(Quest quest)
{
_quests.add(quest);
}
public ArrayList<Quest> getQuests()
{
ArrayList<Quest> quests = new ArrayList<>();
for (Quest quest : _quests)
{
if (quest.getProgress() != -1)
quests.add(quest);
}
return quests;
}
public boolean hasQuest(Quest quest)
{
for (Quest other : getQuests())
{
if (other.getID() == quest.getID())
return true;
}
return false;
}
public Quest getQuest(int id)
{
for (Quest quest : getQuests())
{
if (quest.getID() == id)
return quest;
}
return null;
}
public Quest getQuestFromAll(int id)
{
for (Quest quest : _quests)
{
if (quest.getID() == id)
return quest;
}
return null;
}
public boolean hasQuestFromAll(Quest quest)
{
for (Quest other : _quests)
{
if (other.getID() == quest.getID())
return true;
}
return false;
}
public void removeQuest(int id)
{
Quest toRemove = getQuest(id);
toRemove.setProgress(-1);
}
public ArrayList<Quest> getAllQuests()
{
return _quests;
}
public Hologram getHologram()
{
return _hologram;
}
public void setHologram(Hologram hologram)
{
_hologram = hologram;
}
}

View File

@ -0,0 +1,416 @@
package mineplex.core.quests;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import net.md_5.bungee.api.ChatColor;
import org.apache.commons.lang3.tuple.Triple;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Slime;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import mineplex.core.MiniClientPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Pair;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.donation.DonationManager;
import mineplex.core.google.GoogleSheetsManager;
import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.npc.Npc;
import mineplex.core.npc.NpcManager;
import mineplex.core.quests.command.GetQuestCommand;
import mineplex.core.quests.command.IncrementQuestCommand;
import mineplex.core.quests.command.OpenGuiCommand;
import mineplex.core.quests.repository.QuestRepository;
import mineplex.core.quests.shop.QuestShop;
import mineplex.core.stats.StatsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.quest.client.RedisQuestSupplier;
import mineplex.quest.common.QuestSupplier;
import mineplex.serverdata.redis.messaging.PubSubJedisClient;
import mineplex.serverdata.redis.messaging.PubSubRouter;
import mineplex.serverdata.servers.ServerManager;
/**
* QuestManager
*
* @author xXVevzZXx
*/
public class QuestManager extends MiniClientPlugin<QuestClientData>
{
public static final String QUEST_NAME = "Mineplex Mission";
private static final String GOOGLE_SHEET = "QUESTS_SHEET";
private static final String GOOGLE_TABLE = "Quests";
private QuestRepository _repository;
private GoogleSheetsManager _sheetsManager;
private CoreClientManager _clients;
private DonationManager _donationManager;
private InventoryManager _inventoryManager;
public ArrayList<Quest> _availableQuests;
private QuestSupplier _questSupplier = new RedisQuestSupplier(getPlugin(), new PubSubRouter(new PubSubJedisClient(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection())));
private Npc _questNPC;
private boolean _enableNPC;
private HologramManager _hologramManager;
private boolean _visualTick;
public QuestManager(HologramManager hologramManager, Location npc, InventoryManager inventoryManager, DonationManager donationManager)
{
super("Quest Manager");
_repository = new QuestRepository();
_sheetsManager = require(GoogleSheetsManager.class);
_clients = require(CoreClientManager.class);
_availableQuests = new ArrayList<>();
_donationManager = donationManager;
_inventoryManager = inventoryManager;
_hologramManager = hologramManager;
setupQuests();
_questNPC = require(NpcManager.class).getNpcByName("Mineplex Missions");
if (_questNPC == null)
{
_enableNPC = false;
}
else
{
Slime slime = (Slime) _questNPC.getEntity();
slime.setSize(3);
if (npc != null)
{
_questNPC.setLocation(npc);
}
_enableNPC = true;
}
}
@EventHandler
public void updateCreeper(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER || !_enableNPC)
return;
Slime slime = (Slime)_questNPC.getEntity();
slime.setSize(3);
for (Player player : UtilServer.getPlayers())
{
String prefix = _visualTick ? C.cAqua : C.cDAqua;
updateSlimeVisual(player, prefix);
}
_visualTick = !_visualTick;
}
public void updateSlimeVisual(Player player , String rewardPrefix)
{
if (!_enableNPC)
return;
int availableQuests = 5;
for (int questid : getCurrentQuests())
{
if (Get(player).getQuestFromAll(questid) == null)
continue;
Quest quest = Get(player).getQuestFromAll(questid);
if (quest.isActive())
availableQuests--;
if (!UtilTime.elapsed(quest.getLastCompleted(), 1000*60*60*24))
availableQuests--;
}
Hologram hologram;
QuestClientData client = Get(player);
if (client.getHologram() == null)
{
double yAdd = 2.3;
if(!UtilPlayer.is1_9(player))
{
yAdd = 2.45;
}
hologram = new Hologram(_hologramManager, _questNPC.getLocation().clone().add(0, yAdd, 0), "");
hologram.setHologramTarget(Hologram.HologramTarget.WHITELIST);
hologram.addPlayer(player);
client.setHologram(hologram);
hologram.start();
}
else
{
hologram = client.getHologram();
}
if (availableQuests > 0)
{
// Hologram
String text = rewardPrefix + availableQuests + " Mission" + (availableQuests > 1 ? "s" : "") + " Available";
hologram.setText(text);
}
else
{
String text = C.cGray + "No Missions Available";
hologram.setText(text);
}
}
@Override
public void addCommands()
{
addCommand(new OpenGuiCommand(this));
addCommand(new GetQuestCommand(this));
addCommand(new IncrementQuestCommand(this));
}
public void setupQuests()
{
_availableQuests.clear();
Map<String, List<List<String>>> sheet = _sheetsManager.getSheetData(GOOGLE_SHEET);
List<List<String>> table = new ArrayList<>();
for (String key : sheet.keySet())
{
if (key.equalsIgnoreCase(GOOGLE_TABLE))
table = sheet.get(key);
}
int size = table.size();
for (int i = 1; i < size; i++)
{
String id = table.get(i).get(0);
String name = table.get(i).get(1);
String task = table.get(i).get(2);
String type = table.get(i).get(3);
String cost = table.get(i).get(4);
String reward = table.get(i).get(5);
String trigger = table.get(i).get(6);
String statcompletion = table.get(i).get(7);
String item = table.get(i).get(8);
String rarity = table.get(i).get(9);
_availableQuests.add(new Quest(Integer.parseInt(id), name, task,
Integer.parseInt(cost),
reward,
QuestRarity.getByName(rarity),
type,
TriggerType.getByName(trigger),
item.split(","),
Integer.parseInt(statcompletion)));
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void openGui(PlayerInteractAtEntityEvent event)
{
if (!_enableNPC)
return;
Entity entity = event.getRightClicked();
if (entity.equals(_questNPC.getEntity()))
{
new QuestShop(this, _clients, _donationManager).attemptShopOpen(event.getPlayer());
}
}
@EventHandler
public void openGui(EntityDamageByEntityEvent event)
{
if (!_enableNPC)
return;
if (event.getDamager() instanceof Player)
{
Player player = (Player) event.getDamager();
if (event.getEntity().equals(_questNPC.getEntity()))
{
new QuestShop(this, _clients, _donationManager).attemptShopOpen(player);
}
}
}
@EventHandler
public void playerJoin(PlayerJoinEvent event)
{
QuestClientData questData = Get(event.getPlayer());
_repository.getQuests(_clients.Get(event.getPlayer()), new Callback<ArrayList<Pair<Integer, Triple<Integer, Long, Integer>>>>()
{
@Override
public void run(ArrayList<Pair<Integer, Triple<Integer, Long, Integer>>> data)
{
for (Pair<Integer, Triple<Integer, Long, Integer>> pair : data)
{
int id = pair.getLeft();
int value = pair.getRight().getLeft();
long time = pair.getRight().getMiddle();
int timesCompleted = pair.getRight().getRight();
for (Quest quest : _availableQuests)
{
if (quest.getID() == id)
{
Quest clone = quest.clone();
clone.setProgress(value);
clone.setLastCompleted(time);
clone.setTimesCompleted(timesCompleted);
questData.addQuest(clone);
}
}
}
}
});
}
public Quest getQuestByID(int id)
{
for (Quest quest : _availableQuests)
{
if (quest.getID() == id)
return quest;
}
return null;
}
public void addNewQuest(Player player, Quest quest)
{
QuestClientData data = Get(player);
for (Quest other : data.getAllQuests())
{
if (other.getID() == quest.getID())
{
other.setProgress(0);
_repository.addQuest(_clients.Get(player), other);
return;
}
}
Quest clone = quest.clone();
clone.setProgress(0);
Get(player).addQuest(clone);
_repository.addNew(_clients.Get(player), quest);
}
public void resetQuest(Player player, Quest quest, boolean completed)
{
if (completed)
{
quest.setTimesCompleted(quest.getTimesCompleted() + 1);
quest.setLastCompleted(System.currentTimeMillis());
}
Get(player).removeQuest(quest.getID());
_repository.resetQuest(_clients.Get(player), quest, completed);
}
public void incrementQuest(Player player, Quest quest, int value)
{
quest.increment(value);
if (quest.isCompleted())
{
UtilPlayer.message(player, F.main(QUEST_NAME, "You have completed the " + QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName()));
}
_repository.incrementQuest(_clients.Get(player), quest, value);
}
public Set<Integer> getCurrentQuests()
{
Set<Integer> set = new HashSet<>();
for (mineplex.quest.common.Quest quest : _questSupplier.get())
{
set.add(quest.getUniqueId());
}
return set;
}
public void rewardQuest(Player player, Quest quest, Consumer<Boolean> callback)
{
if (quest.getReward().contains(":"))
{
ChatColor color = ChatColor.YELLOW;
if (quest.getRewardName().equalsIgnoreCase("Shards"))
{
_donationManager.rewardCurrency(GlobalCurrency.TREASURE_SHARD, player, "Completing " + QUEST_NAME + ": " + quest.getID(), Integer.parseInt(quest.getReward().split(":")[1]), callback);
color = ChatColor.AQUA;
}
else if (quest.getRewardName().equalsIgnoreCase("Gems"))
{
_donationManager.rewardCurrency(GlobalCurrency.TREASURE_SHARD, player, "Completing " + QUEST_NAME + ": " + quest.getID(), Integer.parseInt(quest.getReward().split(":")[1]), callback);
color = ChatColor.GREEN;
}
else if (quest.getRewardName().equalsIgnoreCase("XP"))
{
require(StatsManager.class).incrementStat(player, "Global.ExpEarned", quest.getRewardAmount());
callback.accept(true);
}
else
{
_inventoryManager.addItemToInventory(player, quest.getRewardName(), quest.getRewardAmount());
callback.accept(true);
}
UtilPlayer.message(player, F.main(QUEST_NAME, "You have recieved " + color + quest.getRewardAmount() + " " + quest.getRewardName() + " " + ChatColor.GRAY + "for completing: " + ChatColor.YELLOW + quest.getName()));
}
}
public CoreClientManager getClients()
{
return _clients;
}
public DonationManager getDonations()
{
return _donationManager;
}
public InventoryManager getInventoryManager()
{
return _inventoryManager;
}
@Override
protected QuestClientData addPlayer(UUID uuid)
{
return new QuestClientData();
}
@Override
public void saveData(String name, int accountId)
{
Get(name).getHologram().stop();
}
public ArrayList<Quest> getAvailableQuests()
{
return _availableQuests;
}
}

View File

@ -0,0 +1,44 @@
package mineplex.core.quests;
import org.bukkit.ChatColor;
/**
* QuestRarity
*
* @author xXVevzZXx
*/
public enum QuestRarity
{
COMMON("Common", ChatColor.YELLOW), RARE("Rare", ChatColor.LIGHT_PURPLE), LEGENDARY("Legendary", ChatColor.GREEN);
private String _name;
private ChatColor _color;
private QuestRarity(String name, ChatColor color)
{
_name = name;
_color = color;
}
@Override
public String toString()
{
return _name;
}
public ChatColor getColor()
{
return _color;
}
public static QuestRarity getByName(String name)
{
for (QuestRarity rarity : values())
{
if (rarity.toString().equalsIgnoreCase(name))
return rarity;
}
return null;
}
}

View File

@ -0,0 +1,36 @@
package mineplex.core.quests;
/**
* TriggerType
*
* @author xXVevzZXx
*/
public enum TriggerType
{
KILL("Kill"), DIE("Die"), WIN("Win"), LOSE("Lose"), COLLECT("Collect"), PLAY("Play"), COMPLETE("Complete");
private String _name;
private TriggerType(String name)
{
_name = name;
}
@Override
public String toString()
{
return _name;
}
public static TriggerType getByName(String name)
{
for (TriggerType type : values())
{
if (type.toString().equalsIgnoreCase(name))
return type;
}
return null;
}
}

View File

@ -0,0 +1,55 @@
package mineplex.core.quests.command;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
/**
* GetQuestCommand
*
* @author xXVevzZXx
*/
public class GetQuestCommand extends CommandBase<QuestManager>
{
public GetQuestCommand(QuestManager plugin)
{
super(plugin, Rank.ADMIN, "GetMineplexMission");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You have to submit valid arguments"));
return;
}
if (Plugin.getQuestByID(Integer.parseInt(args[0])) == null)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, QuestManager.QUEST_NAME + " not found"));
return;
}
Player player = caller;
if (args.length == 2)
{
if (UtilPlayer.searchExact(args[1]) != null)
player = UtilPlayer.searchExact(args[1]);
}
Quest quest = Plugin.getQuestByID(Integer.parseInt(args[0]));
Plugin.addNewQuest(player, quest);
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "Added " + QuestManager.QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName()));
if (caller != player)
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You gave the " + QuestManager.QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName() + ChatColor.GRAY + " to " + ChatColor.YELLOW + player.getName()));
}
}

View File

@ -0,0 +1,67 @@
package mineplex.core.quests.command;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
/**
* CompleteQuestCommand
*
* @author xXVevzZXx
*/
public class IncrementQuestCommand extends CommandBase<QuestManager>
{
public IncrementQuestCommand(QuestManager plugin)
{
super(plugin, Rank.ADMIN, "IncrementMineplexMission");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 2)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You have to submit valid arguments"));
return;
}
Player player = caller;
if (args.length == 3)
{
if (UtilPlayer.searchExact(args[2]) != null)
player = UtilPlayer.searchExact(args[2]);
}
if (Plugin.Get(player).getQuest(Integer.parseInt(args[0])) == null)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, QuestManager.QUEST_NAME + " not found"));
return;
}
int increment = 0;
try
{
increment = Integer.parseInt(args[1]);
}
catch (NumberFormatException e)
{
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You have to submit a valid number"));
return;
}
Quest quest = Plugin.Get(player).getQuest(Integer.parseInt(args[0]));
Plugin.incrementQuest(player, quest, increment);
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "Incremented " + QuestManager.QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName() + ChatColor.GRAY + " by " + increment));
if (caller != player)
UtilPlayer.message(caller, F.main(QuestManager.QUEST_NAME, "You incremented the " + QuestManager.QUEST_NAME + ": " + ChatColor.YELLOW + quest.getName() + ChatColor.GRAY + " for " + ChatColor.YELLOW + player.getName() + ChatColor.GRAY + " by " + increment));
}
}

View File

@ -0,0 +1,27 @@
package mineplex.core.quests.command;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.quests.QuestManager;
import mineplex.core.quests.shop.QuestShop;
/**
* OpenGuiCommand
*
* @author xXVevzZXx
*/
public class OpenGuiCommand extends CommandBase<QuestManager>
{
public OpenGuiCommand(QuestManager plugin)
{
super(plugin, Rank.ALL, "Missions");
}
@Override
public void Execute(Player caller, String[] args)
{
new QuestShop(Plugin, Plugin.getClients(), Plugin.getDonations()).attemptShopOpen(caller);
}
}

View File

@ -0,0 +1,60 @@
package mineplex.core.quests.event;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import mineplex.core.quests.Quest;
/**
* QuestBuyEvent
*
* @author xXVevzZXx
*/
public class QuestInteractEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private boolean _cancelled = false;
private Quest _quest;
private String _cancelReason;
public QuestInteractEvent(Quest quest)
{
_quest = quest;
}
public Quest getQuest()
{
return _quest;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public boolean isCancelled()
{
return _cancelled;
}
public void setCancelled(String reason)
{
_cancelled = true;
_cancelReason = reason;
}
public String getCancelMessage()
{
return _cancelReason;
}
}

View File

@ -0,0 +1,140 @@
package mineplex.core.quests.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.apache.commons.lang3.tuple.Triple;
import mineplex.core.account.CoreClient;
import mineplex.core.common.Pair;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UtilServer;
import mineplex.core.quests.Quest;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnLong;
/**
* QuestRepository
*
* @author xXVevzZXx
*/
public class QuestRepository extends RepositoryBase
{
private static final String INSTERT_NEW_QUEST = "INSERT INTO accountQuest (accountId, questId, progress, questCompletion, lastCompleted) VALUES (?, ?, ?, ?, ?);";
private static final String INCREMENT_QUEST = "UPDATE accountQuest SET progress=progress+? WHERE accountId=? AND questId=?;";
private static final String RESET_QUEST = "UPDATE accountQuest SET progress=-1 WHERE accountId=? AND questId=?;";
private static final String START_QUEST = "UPDATE accountQuest SET progress=0 WHERE accountId=? AND questId=?;";
private static final String COMPLETE_QUEST = "UPDATE accountQuest SET progress=-1, questCompletion=questCompletion+1, lastCompleted=? WHERE accountId=? AND questId=?;";
private static final String FETCH_QUESTS = "SELECT questId, progress, questCompletion, lastCompleted FROM accountQuest WHERE accountId=?";
public String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS accountQuest (id INT NOT NULL AUTO_INCREMENT, accountId INT NOT NULL, questId INT NOT NULL, progress INT, questCompletion INT, lastCompleted BIGINT NOT NULL, PRIMARY KEY (id), FOREIGN KEY (accountId) REFERENCES accounts (id), UNIQUE INDEX questIndex (accountId, questId), INDEX progressIndex (progress), INDEX completionIndex (questCompletion));";
public QuestRepository()
{
super(DBPool.getAccount());
createTable();
}
public void createTable()
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeUpdate(CREATE_TABLE);
}
});
}
public void getQuests(CoreClient client, Callback<ArrayList<Pair<Integer, Triple<Integer, Long, Integer>>>> callback)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeQuery(FETCH_QUESTS, new ResultSetCallable()
{
@Override
public void processResultSet(ResultSet resultSet) throws SQLException
{
ArrayList<Pair<Integer, Triple<Integer, Long, Integer>>> list = new ArrayList<>();
while (resultSet.next())
{
list.add(Pair.create(resultSet.getInt(1), Triple.of(resultSet.getInt(2), resultSet.getLong(4), resultSet.getInt(3))));
}
callback.run(list);
}
} ,new ColumnInt("accountId", client.getAccountId()));
}
});
}
public void resetQuest(CoreClient client, Quest quest, boolean completed)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
if (completed)
{
executeUpdate(COMPLETE_QUEST, new ColumnLong("lastCompleted", System.currentTimeMillis()), new ColumnInt("accountId", client.getAccountId()), new ColumnInt("questId", quest.getID()));
}
else
{
executeUpdate(RESET_QUEST, new ColumnInt("accountId", client.getAccountId()), new ColumnInt("questId", quest.getID()));
}
}
});
}
public void addQuest(CoreClient client, Quest quest)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeUpdate(START_QUEST, new ColumnInt("accountId", client.getAccountId()), new ColumnInt("questId", quest.getID()));
}
});
}
public void addNew(CoreClient client, Quest quest)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeInsert(INSTERT_NEW_QUEST, null,
new ColumnInt("accountId", client.getAccountId()),
new ColumnInt("questId", quest.getID()),
new ColumnInt("progress", 0),
new ColumnInt("questCompletion", 0),
new ColumnLong("lastCompleted", (long) 0));
}
});
}
public void incrementQuest(CoreClient client, Quest quest, int value)
{
UtilServer.runAsync(new Runnable()
{
@Override
public void run()
{
executeUpdate(INCREMENT_QUEST, new ColumnInt("progress", value), new ColumnInt("accountId", client.getAccountId()), new ColumnInt("questId", quest.getID()));
}
});
}
}

View File

@ -0,0 +1,93 @@
package mineplex.core.quests.shop;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
import mineplex.core.quests.event.QuestInteractEvent;
import mineplex.core.recharge.Recharge;
import mineplex.core.shop.confirmation.ConfirmationPage;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.SalesPackageBase;
import mineplex.core.shop.item.SalesPackageProcessor;
/**
* BuyQuestButton
*
* @author xXVevzZXx
*/
public class BuyQuestButton implements IButton
{
private final static int MAX_QUESTS = 5;
private QuestManager _questManager;
private QuestPage _page;
private Quest _quest;
public BuyQuestButton(QuestManager questManager, QuestPage page, Quest quest)
{
_questManager = questManager;
_quest = quest;
_page = page;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (!Recharge.Instance.use(player, "Buy Mineplex Mission", 1000, false, false))
{
return;
}
if (_questManager.Get(player).hasQuest(_quest))
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You already own that " + QuestManager.QUEST_NAME + "!"));
return;
}
if (_questManager.Get(player).getQuests().size() >= MAX_QUESTS)
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You can't own more than " + MAX_QUESTS + " active " + QuestManager.QUEST_NAME + " at once!"));
return;
}
if (_questManager.Get(player).hasQuestFromAll(_quest))
{
if (!UtilTime.elapsed(_questManager.Get(player).getQuestFromAll(_quest.getID()).getLastCompleted(), 1000*60*60*24))
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You already completed that " + QuestManager.QUEST_NAME + " today!"));
return;
}
}
QuestInteractEvent event = UtilServer.CallEvent(new QuestInteractEvent(_quest));
if (event.isCancelled())
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, event.getCancelMessage()));
return;
}
SalesPackageBase salesPackage = new QuestSale(ChatColor.YELLOW + "" + ChatColor.BOLD + _quest.getName(), Material.PAPER, _quest.getCost());
_page.getShop().openPageForPlayer(player, new ConfirmationPage<>(player, _page, new SalesPackageProcessor(player, GlobalCurrency.GEM, salesPackage, _page.getDonationManager(), () ->
{
_questManager.addNewQuest(player, _quest);
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You have bought: " + ChatColor.YELLOW + _quest.getName()));
player.closeInventory();
new QuestShop(_questManager, _questManager.getClients(), _questManager.getDonations()).attemptShopOpen(player);
}), salesPackage.buildIcon()));
}
}

View File

@ -0,0 +1,156 @@
package mineplex.core.quests.shop;
import java.util.ArrayList;
import java.util.Arrays;
import org.apache.commons.lang3.ArrayUtils;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.UtilTime;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.page.ShopPageBase;
/**
* QuestPage
*
* @author xXVevzZXx
*/
public class QuestPage extends ShopPageBase<QuestManager, QuestShop>
{
private QuestShop _questShop;
private QuestManager _manager;
public QuestPage(QuestManager plugin, QuestShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player)
{
super(plugin, shop, clientManager, donationManager, QuestManager.QUEST_NAME + " Page", player, 27);
_questShop = shop;
_manager = plugin;
buildPage();
}
@Override
protected void buildPage()
{
int i = 0;
setItem(i, ItemStackFactory.Instance.CreateStack(Material.EMERALD, (byte) 0, 1, ChatColor.RESET + "" + ChatColor.BOLD + "Available " + QuestManager.QUEST_NAME + "s"));
{
int currentSlot = 4;
int diff = 0;
boolean forward = true;
for (int questID : getQuestShop().getQuestManager().getCurrentQuests())
{
if (forward)
{
currentSlot += diff;
}
else
{
currentSlot -= diff;
}
diff++;
forward = !forward;
Quest playerQuest = _shop.getQuestManager().Get(_player).getQuestFromAll(questID);
if (playerQuest != null)
{
if (!UtilTime.elapsed(playerQuest.getLastCompleted(), 1000*60*60*24))
{
continue;
}
if (playerQuest.isActive())
{
continue;
}
}
Quest quest = _shop.getQuestManager().getQuestByID(questID);
ItemStack item = new ItemStack(Material.PAPER);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.YELLOW + "" + ChatColor.BOLD + quest.getName());
meta.setLore(Arrays.asList(
ChatColor.LIGHT_PURPLE + quest.getTask(),
"",
ChatColor.GRAY + "Cost: " + ChatColor.GREEN + quest.getCost() + " Gems",
ChatColor.GRAY + "Reward: " + ChatColor.AQUA + quest.getRewardAmount() + " " + quest.getRewardName(),
"",
quest.getRarity().getColor() + "" + ChatColor.BOLD + quest.getRarity().toString(),
"",
ChatColor.GREEN + "Click to buy " + QuestManager.QUEST_NAME + "!"
));
item.setItemMeta(meta);
addButton(i + currentSlot, item, new BuyQuestButton(_manager, this, quest));
}
}
i = 9;
while (i < (9*2))
{
setItem(i, ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, DyeColor.BLACK.getData()));
i++;
}
i = 9*2;
addButton(i, ItemStackFactory.Instance.CreateStack(Material.EMPTY_MAP, (byte) 0, 1, ChatColor.RESET + "" + ChatColor.BOLD + QuestManager.QUEST_NAME + " Stats"), new IButton()
{
@Override
public void onClick(Player player, ClickType clickType)
{
player.closeInventory();
new QuestStatShop(_manager, _manager.getClients(), _manager.getDonations()).attemptShopOpen(player);
}
});
{
int currentSlot = 4;
int diff = 0;
boolean forward = true;
for (Quest quest : _shop.getQuestManager().Get(_player).getQuests())
{
if (forward)
{
currentSlot += diff;
}
else
{
currentSlot -= diff;
}
diff++;
forward = !forward;
ItemStack item = new ItemStack(Material.PAPER);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.YELLOW + "" + ChatColor.BOLD + quest.getName());
meta.setLore(Arrays.asList(ArrayUtils.addAll(quest.getQuestInfo(),
"",
(quest.isCompleted() ? ChatColor.GREEN + "Left Click to Complete" : ChatColor.RED + "Shift Right-Click to cancel")
)));
item.setItemMeta(meta);
item.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
addButton(i + currentSlot, item, new RedeemDeclineQuestButton(_donationManager, _manager, quest));
}
}
}
public QuestShop getQuestShop()
{
return _questShop;
}
}

View File

@ -0,0 +1,25 @@
package mineplex.core.quests.shop;
import org.bukkit.Material;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.shop.item.SalesPackageBase;
/**
* QuestSale
*
* @author xXVevzZXx
*/
public class QuestSale extends SalesPackageBase
{
public QuestSale(String name, Material mat, int cost)
{
super(name, mat, (byte) 0, new String[] {}, cost);
KnownPackage = false;
OneTimePurchaseOnly = false;
// CurrencyCostMap.clear();
CurrencyCostMap.put(GlobalCurrency.GEM, cost);
}
}

View File

@ -0,0 +1,34 @@
package mineplex.core.quests.shop;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.quests.QuestManager;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
/**
* QuestShop
*
* @author xXVevzZXx
*/
public class QuestShop extends ShopBase<QuestManager>
{
public QuestShop(QuestManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super(plugin, clientManager, donationManager, QuestManager.QUEST_NAME + " Shop");
}
@Override
protected ShopPageBase<QuestManager, ? extends ShopBase<QuestManager>> buildPagesFor(Player player)
{
return new QuestPage(getPlugin(), this, getClientManager(), getDonationManager(), player);
}
public QuestManager getQuestManager()
{
return getPlugin();
}
}

View File

@ -0,0 +1,35 @@
package mineplex.core.quests.shop;
import org.bukkit.entity.Player;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.quests.QuestManager;
import mineplex.core.shop.ShopBase;
import mineplex.core.shop.page.ShopPageBase;
/**
* QuestStatShop
*
* @author xXVevzZXx
*/
public class QuestStatShop extends ShopBase<QuestManager>
{
public QuestStatShop(QuestManager plugin, CoreClientManager clientManager, DonationManager donationManager)
{
super(plugin, clientManager, donationManager, QuestManager.QUEST_NAME + " Stats");
}
@Override
protected ShopPageBase<QuestManager, ? extends ShopBase<QuestManager>> buildPagesFor(Player player)
{
return new QuestStatsPage(getPlugin(), this, getClientManager(), getDonationManager(), player, 0);
}
public QuestManager getQuestManager()
{
return getPlugin();
}
}

View File

@ -0,0 +1,128 @@
package mineplex.core.quests.shop;
import java.util.Arrays;
import org.apache.commons.lang3.ArrayUtils;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import mineplex.core.account.CoreClientManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestClientData;
import mineplex.core.quests.QuestManager;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.page.ShopPageBase;
/**
* QuestStatsPage
*
* @author xXVevzZXx
*/
public class QuestStatsPage extends ShopPageBase<QuestManager, QuestStatShop>
{
private QuestStatShop _questShop;
private QuestManager _manager;
private int _siteIndex;
public QuestStatsPage(QuestManager plugin, QuestStatShop shop, CoreClientManager clientManager, DonationManager donationManager, Player player, int site)
{
super(plugin, shop, clientManager, donationManager, QuestManager.QUEST_NAME + " Stats", player, 6*9);
_siteIndex = site;
_questShop = shop;
_manager = plugin;
buildPage();
}
@Override
protected void buildPage()
{
removeButton(5*9);
removeButton((6*9) - 1);
int questID = (_siteIndex * 5 * 9);
for (int i = 0; i < 9*5; i++)
{
Quest quest = _manager.getQuestByID(questID);
if (quest == null)
{
setItem(i, null);
questID++;
continue;
}
QuestClientData data = _manager.Get(getPlayer());
ItemStack item = ItemStackFactory.Instance.CreateStack(Material.WOOL, DyeColor.GRAY.getWoolData(), 1, ChatColor.YELLOW + quest.getName());
if (data.hasQuestFromAll(quest))
{
Quest used = data.getQuestFromAll(questID);
item = ItemStackFactory.Instance.CreateStack(Material.PAPER, (byte) 0, 1, ChatColor.YELLOW + used.getName());
ItemMeta meta = item.getItemMeta();
meta.setLore(Arrays.asList(ArrayUtils.addAll(used.getQuestInfo(),
"",
ChatColor.GRAY + "Times Completed: " + ChatColor.YELLOW + used.getTimesCompleted()
)));
item.setItemMeta(meta);
}
setItem(i, item);
questID++;
}
if (_siteIndex > 0)
{
addButton(5*9, ItemStackFactory.Instance.CreateStack(Material.SIGN, (byte) 0, 1, ChatColor.YELLOW + "Previous Page"), new IButton()
{
@Override
public void onClick(Player player, ClickType clickType)
{
_siteIndex--;
buildPage();
}
});
}
if (((_siteIndex + 1) * 5 * 9) <= _manager.getAvailableQuests().size())
{
addButton((6*9) - 1, ItemStackFactory.Instance.CreateStack(Material.SIGN, (byte) 0, 1, ChatColor.YELLOW + "Next Page"), new IButton()
{
@Override
public void onClick(Player player, ClickType clickType)
{
_siteIndex++;
buildPage();
}
});
}
addButton(5*9 + 4, ItemStackFactory.Instance.CreateStack(Material.SIGN, (byte) 0, 1, ChatColor.YELLOW + "Back to " + QuestManager.QUEST_NAME + "s"), new IButton()
{
@Override
public void onClick(Player player, ClickType clickType)
{
player.closeInventory();
new QuestShop(_manager, getClientManager(), getDonationManager()).attemptShopOpen(player);
}
});
}
public QuestStatShop getQuestStatsShop()
{
return _questShop;
}
}

View File

@ -0,0 +1,101 @@
package mineplex.core.quests.shop;
import java.util.function.Consumer;
import javax.jws.Oneway;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.donation.DonationManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.quests.Quest;
import mineplex.core.quests.QuestManager;
import mineplex.core.quests.event.QuestInteractEvent;
import mineplex.core.recharge.Recharge;
import mineplex.core.shop.item.IButton;
/**
* RedeemDeclineQuest
*
* @author xXVevzZXx
*/
public class RedeemDeclineQuestButton implements IButton
{
private QuestManager _questManager;
private DonationManager _donations;
private Quest _quest;
public RedeemDeclineQuestButton(DonationManager donations, QuestManager questManager, Quest quest)
{
_questManager = questManager;
_donations = donations;
_quest = quest;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (!Recharge.Instance.use(player, "Decline Mineplex Mission", 1000, false, false))
{
return;
}
if (!_questManager.Get(player).hasQuest(_quest))
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You don't own that " + QuestManager.QUEST_NAME + "!"));
return;
}
QuestInteractEvent event = UtilServer.CallEvent(new QuestInteractEvent(_quest));
if (event.isCancelled())
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, event.getCancelMessage()));
return;
}
if (clickType == ClickType.SHIFT_RIGHT)
{
if (_quest.isCompleted())
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You can't cancel a completed " + QuestManager.QUEST_NAME + "!"));
return;
}
_questManager.resetQuest(player, _quest, false);
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You have cancelled that " + QuestManager.QUEST_NAME + "!"));
}
if (clickType == ClickType.LEFT)
{
if (!_quest.isCompleted())
{
UtilPlayer.message(player, F.main(QuestManager.QUEST_NAME, "You haven't completed that " + QuestManager.QUEST_NAME + " yet!"));
return;
}
_questManager.rewardQuest(player, _quest, new Consumer<Boolean>()
{
@Override
public void accept(Boolean succes)
{
if (succes)
{
_questManager.resetQuest(player, _quest, true);
player.closeInventory();
}
}
});
}
player.closeInventory();
new QuestShop(_questManager, _questManager.getClients(), _donations).attemptShopOpen(player);
}
}

View File

@ -78,7 +78,7 @@ public class Track implements Listener
return this._trackRequirements;
}
public final String getStatName()
public String getStatName()
{
return "track." + _id;
}

View File

@ -9,6 +9,7 @@ import java.util.function.Consumer;
import mineplex.core.titles.tracks.award.AlienInvasionTrack;
import mineplex.core.titles.tracks.award.AprilFools2017Track;
import mineplex.core.titles.tracks.standard.GemHuntersTrack;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
@ -79,6 +80,7 @@ public class TrackManager extends MiniPlugin
// registerTrack(new SurvivorTrack());
registerTrack(new LevelerTrack());
registerTrack(new PerfectionistTrack());
registerTrack(new GemHuntersTrack());
// Awarded tracks
registerTrack(new Bridges2017Track());

View File

@ -0,0 +1,71 @@
package mineplex.core.titles.tracks.standard;
import mineplex.core.titles.tracks.Track;
import mineplex.core.titles.tracks.TrackFormat;
import mineplex.core.titles.tracks.TrackTier;
import net.md_5.bungee.api.ChatColor;
public class GemHuntersTrack extends Track
{
public GemHuntersTrack()
{
super("gem-hunters-gems", "GH Millionaire", "This track is unlocked by earning gems in Gem Hunters");
getRequirements()
.addTier(new TrackTier(
"Beggar",
"Gain 1,000 Gems in Gem Hunters",
this::getStat,
1000,
new TrackFormat(ChatColor.GRAY)
))
.addTier(new TrackTier(
"Poor",
"Gain 5,000 Gems in Gem Hunters",
this::getStat,
5000,
new TrackFormat(ChatColor.AQUA)
))
.addTier(new TrackTier(
"Middle Class",
"Gain 7,500 Gems in Gem Hunters",
this::getStat,
7500,
new TrackFormat(ChatColor.GREEN)
))
.addTier(new TrackTier(
"Wealthy",
"Gain 10,000 Gems in Gem Hunters",
this::getStat,
10000,
new TrackFormat(ChatColor.DARK_GREEN)
))
.addTier(new TrackTier(
"Loaded",
"Gain 25,000 Gems in Gem Hunters",
this::getStat,
25000,
new TrackFormat(ChatColor.GOLD)
))
.addTier(new TrackTier(
"Millionaire",
"Gain 50,000 Gems in Gem Hunters",
this::getStat,
50000,
new TrackFormat(ChatColor.GOLD, ChatColor.YELLOW)
));
getRequirements()
.withRequirement(1, "Gem Earned in Gem Hunters");
}
/**
* Overriding this means we can hit two birds with one stat.
*/
@Override
public String getStatName()
{
return "Gem Hunters.GemsEarned";
}
}

View File

@ -176,22 +176,21 @@ public class TreasureLocation implements Listener
Treasure treasure = new Treasure(_treasureManager, player, rewards, treasureType.getRewardType(), _chestBlock, _chestSpawns, treasureType, _treasureManager.getBlockRestore(), _hologramManager, _statusManager);
_currentTreasure = treasure;
TreasureStartEvent startEvent = new TreasureStartEvent(player, treasure, Arrays.asList(rewards));
UtilServer.CallEvent(startEvent);
UtilTextMiddle.display(treasureType.getName(), "Choose " + rewards.length + " " + UtilText.plural("Chest", rewards.length) + " To Open", 20, 180, 20, player);
UtilPlayer.message(player, F.main("Treasure", "Choose " + rewards.length + " " + UtilText.plural("Chest", rewards.length) + " To Open"));
Location teleportLocation = treasure.getCenterBlock().getLocation().add(0.5, 0, 0.5);
teleportLocation.setPitch(player.getLocation().getPitch());
teleportLocation.setYaw(player.getLocation().getYaw());
for (Entity entity : player.getNearbyEntities(3, 3, 3))
{
UtilAction.velocity(entity, UtilAlg.getTrajectory(entity.getLocation(), treasure.getCenterBlock().getLocation()).multiply(-1), 1.5, true, 0.8, 0, 1.0, true);
}
Location teleportLocation = treasure.getCenterBlock().getLocation().add(0.5, 0, 0.5);
teleportLocation.setPitch(player.getLocation().getPitch());
teleportLocation.setYaw(player.getLocation().getYaw());
player.teleport(teleportLocation);
TreasureStartEvent startEvent = new TreasureStartEvent(player, treasure, Arrays.asList(rewards));
UtilServer.CallEvent(startEvent);
UtilTextMiddle.display(treasureType.getName(), "Choose " + rewards.length + " " + UtilText.plural("Chest", rewards.length) + " To Open", 20, 180, 20, player);
UtilPlayer.message(player, F.main("Treasure", "Choose " + rewards.length + " " + UtilText.plural("Chest", rewards.length) + " To Open"));
_treasureManager.addOpenStat(player, treasureType);
}
@ -363,6 +362,10 @@ public class TreasureLocation implements Listener
{
return;
}
if (_currentTreasure.getCenterBlock().getWorld() != event.getTo().getWorld())
{
return;
}
double toDistanceFromCenter = _currentTreasure.getCenterBlock().getLocation().add(0.5, 1.5, 0.5).distanceSquared(event.getTo());
if (toDistanceFromCenter <= 16)
{

View File

@ -0,0 +1,114 @@
package mineplex.database.tables;
import org.jooq.impl.TableImpl;
/**
* This class is generated by jOOQ.
*/
@javax.annotation.Generated(
value = {
"http://www.jooq.org",
"jOOQ version:3.5.2"
},
comments = "This class is generated by jOOQ"
)
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class AccountQuest //extends TableImpl<mineplex.database.tables.records.AccountQuestRecord> implements java.io.Serializable, java.lang.Cloneable
{
// /**
// *
// */
// private static final long serialVersionUID = -8158716179851336044L;
//
// /**
// * The reference instance of <code>Account.accountStat</code>
// */
// public static final mineplex.database.tables.AccountStat accountStat = new mineplex.database.tables.AccountStat();
//
// /**
// * The class holding records for this type
// */
// @Override
// public java.lang.Class<mineplex.database.tables.records.AccountQuestRecord> getRecordType() {
// return mineplex.database.tables.records.AccountQuestRecord.class;
// }
//
// /**
// * The column <code>Account.accountStat.accountId</code>.
// */
// public final org.jooq.TableField<mineplex.database.tables.records.AccountQuestRecord, java.lang.Integer> accountId = createField("accountId", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
//
// /**
// * The column <code>Account.accountStat.statId</code>.
// */
// public final org.jooq.TableField<mineplex.database.tables.records.AccountQuestRecord, java.lang.Integer> statId = createField("statId", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
//
// /**
// * The column <code>Account.accountStat.value</code>.
// */
// public final org.jooq.TableField<mineplex.database.tables.records.AccountQuestRecord, org.jooq.types.ULong> value = createField("value", org.jooq.impl.SQLDataType.BIGINTUNSIGNED.defaulted(true), this, "");
//
// /**
// * Create a <code>Account.accountStat</code> table reference
// */
// public AccountQuest()
// {
// super("accountquest", null);
// }
//
// /**
// * Create an aliased <code>Account.accountStat</code> table reference
// */
// public AccountQuest(java.lang.String alias) {
// this(alias, mineplex.database.tables.AccountQuest.accountStat);
// }
//
// private AccountQuest(java.lang.String alias, org.jooq.Table<mineplex.database.tables.records.AccountQuestRecord> aliased) {
// this(alias, aliased, null);
// }
//
// private AccountQuest(java.lang.String alias, org.jooq.Table<mineplex.database.tables.records.AccountQuestRecord> aliased, org.jooq.Field<?>[] parameters) {
// super(alias, mineplex.database.Account.Account, aliased, parameters, "");
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public org.jooq.UniqueKey<mineplex.database.tables.records.AccountStatRecord> getPrimaryKey() {
// return mineplex.database.Keys.KEY_accountStat_PRIMARY;
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public java.util.List<org.jooq.UniqueKey<mineplex.database.tables.records.AccountStatRecord>> getKeys() {
// return java.util.Arrays.<org.jooq.UniqueKey<mineplex.database.tables.records.AccountStatRecord>>asList(mineplex.database.Keys.KEY_accountStat_PRIMARY);
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public java.util.List<org.jooq.ForeignKey<mineplex.database.tables.records.AccountStatRecord, ?>> getReferences() {
// return java.util.Arrays.<org.jooq.ForeignKey<mineplex.database.tables.records.AccountStatRecord, ?>>asList(mineplex.database.Keys.accountStat_account, mineplex.database.Keys.accountStat_stat);
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public mineplex.database.tables.AccountStat as(java.lang.String alias) {
// return new mineplex.database.tables.AccountStat(alias, this);
// }
//
// /**
// * Rename this table
// */
// public mineplex.database.tables.AccountStat rename(java.lang.String name) {
// return new mineplex.database.tables.AccountStat(name, null);
// }
}

View File

@ -0,0 +1,202 @@
package mineplex.database.tables.records;
import org.jooq.Table;
/**
* AccountQuest
*
* @author xXVevzZXx
*/
public class AccountQuestRecord //extends org.jooq.impl.UpdatableRecordImpl<mineplex.database.tables.records.AccountQuestRecord> implements java.io.Serializable, java.lang.Cloneable, org.jooq.Record3<java.lang.Integer, java.lang.Integer, org.jooq.types.ULong>
{
//
// /**
// *
// */
// private static final long serialVersionUID = 5171965369180094201L;
//
// public AccountQuestRecord(Table<AccountQuestRecord> table)
// {
// super(table);
// }
//
// /**
// * Setter for <code>Account.accountStat.accountId</code>.
// */
// public void setAccountId(java.lang.Integer value) {
// setValue(0, value);
// }
//
// /**
// * Getter for <code>Account.accountStat.accountId</code>.
// */
// public java.lang.Integer getAccountId() {
// return (java.lang.Integer) getValue(0);
// }
//
// /**
// * Setter for <code>Account.accountStat.statId</code>.
// */
// public void setStatId(java.lang.Integer value) {
// setValue(1, value);
// }
//
// /**
// * Getter for <code>Account.accountStat.statId</code>.
// */
// public java.lang.Integer getStatId() {
// return (java.lang.Integer) getValue(1);
// }
//
// /**
// * Setter for <code>Account.accountStat.value</code>.
// */
// public void setValue(org.jooq.types.ULong value) {
// setValue(2, value);
// }
//
// /**
// * Getter for <code>Account.accountStat.value</code>.
// */
// public org.jooq.types.ULong getValue() {
// return (org.jooq.types.ULong) getValue(2);
// }
//
// // -------------------------------------------------------------------------
// // Primary key information
// // -------------------------------------------------------------------------
//
// /**
// * {@inheritDoc}
// */
// @Override
// public org.jooq.Record2<java.lang.Integer, java.lang.Integer> key() {
// return (org.jooq.Record2) super.key();
// }
//
// // -------------------------------------------------------------------------
// // Record3 type implementation
// // -------------------------------------------------------------------------
//
// /**
// * {@inheritDoc}
// */
// @Override
// public org.jooq.Row3<java.lang.Integer, java.lang.Integer, org.jooq.types.ULong> fieldsRow() {
// return (org.jooq.Row3) super.fieldsRow();
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public org.jooq.Row3<java.lang.Integer, java.lang.Integer, org.jooq.types.ULong> valuesRow() {
// return (org.jooq.Row3) super.valuesRow();
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public org.jooq.Field<java.lang.Integer> field1() {
// return mineplex.database.tables.AccountStat.accountStat.accountId;
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public org.jooq.Field<java.lang.Integer> field2() {
// return mineplex.database.tables.AccountStat.accountStat.statId;
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public org.jooq.Field<org.jooq.types.ULong> field3() {
// return mineplex.database.tables.AccountStat.accountStat.value;
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public java.lang.Integer value1() {
// return getAccountId();
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public java.lang.Integer value2() {
// return getStatId();
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public org.jooq.types.ULong value3() {
// return getValue();
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public AccountStatRecord value1(java.lang.Integer value) {
// setAccountId(value);
// return this;
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public AccountStatRecord value2(java.lang.Integer value) {
// setStatId(value);
// return this;
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public AccountStatRecord value3(org.jooq.types.ULong value) {
// setValue(value);
// return this;
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public AccountStatRecord values(java.lang.Integer value1, java.lang.Integer value2, org.jooq.types.ULong value3) {
// return this;
// }
//
// // -------------------------------------------------------------------------
// // Constructors
// // -------------------------------------------------------------------------
//
// /**
// * Create a detached AccountStatRecord
// */
// public AccountStatRecord() {
// super(mineplex.database.tables.AccountStat.accountStat);
// }
//
// /**
// * Create a detached, initialised AccountStatRecord
// */
// public AccountStatRecord(java.lang.Integer accountId, java.lang.Integer statId, org.jooq.types.ULong value) {
// super(mineplex.database.tables.AccountStat.accountStat);
//
// setValue(0, accountId);
// setValue(1, statId);
// setValue(2, value);
// }
}

View File

@ -2,17 +2,13 @@ package mineplex.enjinTranslator;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.AbstractMap;
import java.util.Date;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClient;
@ -20,15 +16,12 @@ import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.NautHashMap;
import mineplex.core.donation.DonationManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
import mineplex.core.punish.Category;
import mineplex.core.punish.Punish;
import mineplex.core.server.util.TransactionResponse;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.enjinTranslator.purchase.PurchaseManager;
public class Enjin extends MiniPlugin implements CommandExecutor
@ -40,7 +33,6 @@ public class Enjin extends MiniPlugin implements CommandExecutor
private PowerPlayClubRepository _powerPlayClubRepository;
private Punish _punish;
private NautHashMap<String, Entry<UUID, Long>> _cachedUUIDs = new NautHashMap<String, Entry<UUID, Long>>();
private static Object _commandLock = new Object();
public long _lastPoll = System.currentTimeMillis() - 120000;
@ -63,21 +55,6 @@ public class Enjin extends MiniPlugin implements CommandExecutor
plugin.getCommand("pull").setExecutor(this);
}
@EventHandler
public void expireCachedUUIDs(UpdateEvent event)
{
if (event.getType() != UpdateType.MIN_01)
return;
for (Iterator<Entry<String, Entry<UUID, Long>>> iterator = _cachedUUIDs.entrySet().iterator(); iterator.hasNext(); )
{
Entry<String, Entry<UUID, Long>> entry = iterator.next();
if (System.currentTimeMillis() > entry.getValue().getValue())
iterator.remove();
}
}
@Override
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args)
{
@ -90,35 +67,26 @@ public class Enjin extends MiniPlugin implements CommandExecutor
if (label.equalsIgnoreCase("enjin_mineplex"))
{
final String name = args[1];
final UUID uuid;
try
{
uuid = UUID.fromString(args[1]);
}
catch (IllegalArgumentException e)
{
System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + args[1] + "; invalid UUID.");
return true;
}
_clientManager.loadClientByName(name, client ->
_clientManager.loadClientByUUID(uuid, client ->
{
if (client == null)
{
System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + ", isn't in our database.");
System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + uuid + ", isn't in our database.");
}
else
{
UUID uuid = null;
if (_cachedUUIDs.containsKey(name))
uuid = _cachedUUIDs.get(name).getKey();
else
{
// Fails if not in DB and if duplicate.
uuid = _clientManager.loadUUIDFromDB(name);
}
if (uuid == null)
{
System.out.println("[" + _dateFormat.format(new Date()) + "] ERROR processing " + name + ", no UUID.");
return;
}
final UUID playerUUID = uuid;
_cachedUUIDs.put(name, new AbstractMap.SimpleEntry<UUID, Long>(playerUUID, System.currentTimeMillis() + 240000));
final String name = client.getName();
if (args[0].equalsIgnoreCase("chargeback"))
{
@ -129,15 +97,15 @@ public class Enjin extends MiniPlugin implements CommandExecutor
if (!checkForClansPurchase(args, name, client))
{
if (!checkForBoosterPurchase(args, name, playerUUID, client))
if (!checkForBoosterPurchase(args, name, uuid, client))
{
if (!checkForCoinPurchase(args, name, playerUUID, client))
if (!checkForCoinPurchase(args, name, uuid, client))
{
if (!checkForRankPurchase(args, name, playerUUID, client))
if (!checkForRankPurchase(args, name, uuid, client))
{
if (!checkForPurchase(args, name, client))
{
if (!checkForPowerPlayClub(args, name, playerUUID, client))
if (!checkForPowerPlayClub(args, name, uuid, client))
{
StringBuilder sb = new StringBuilder();

View File

@ -674,7 +674,7 @@ public class HubManager extends MiniPlugin implements IChatMessageFormatter
_lastPlayerCount = playerCount;
Bukkit.getOnlinePlayers().stream().filter(player -> _clientManager.Get(player).GetRank() == Rank.ALL).forEach(player ->
{
UtilTextBottom.display(C.cGray + "Visit " + F.elem("http://www.mineplex.com/shop") + " for exclusive perks!", player);
UtilTextBottom.display(C.cGray + "Visit " + F.elem("http://www.mineplex.com/shop") + " for exclusive hattori!", player);
});
}

View File

@ -16,7 +16,7 @@ import mineplex.core.antihack.guardians.GuardianManager;
import mineplex.core.aprilfools.AprilFoolsManager;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.boosters.BoosterManager;
import mineplex.core.brawl.fountain.FountainManager;
import mineplex.hub.brawl.fountain.FountainManager;
import mineplex.core.chat.Chat;
import mineplex.core.chatsnap.SnapshotManager;
import mineplex.core.chatsnap.SnapshotPlugin;
@ -188,7 +188,7 @@ public class Hub extends JavaPlugin implements IRelation
QueueManager queueManager = new QueueManager(this, clientManager, donationManager, eloManager, partyManager);
ServerManager serverManager = new ServerManager(this, clientManager, donationManager, portal, partyManager, serverStatusManager, hubManager, queueManager, boosterManager);
new FountainManager(this, clientManager, donationManager, hologramManager, statsManager, serverManager);
new FountainManager(this, serverManager);
Chat chat = new Chat(this, incognito, clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName());
new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, chat);

View File

@ -104,6 +104,7 @@ import mineplex.core.preferences.Preference;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.punish.Punish;
import mineplex.core.quests.QuestManager;
import mineplex.core.scoreboard.MineplexScoreboard;
import mineplex.core.scoreboard.ScoreboardManager;
import mineplex.core.stats.StatsManager;
@ -178,6 +179,7 @@ public class HubManager extends MiniClientPlugin<HubClient> implements IChatMess
// private HalloweenSpookinessManager _halloweenManager;
// private TrickOrTreatManager _trickOrTreatManager;
private MavericksManager _mavericksManager;
private QuestManager _questManager;
private final TwoFactorAuth _twofactor = Managers.require(TwoFactorAuth.class);
private HologramManager _hologramManager;
@ -291,6 +293,8 @@ public class HubManager extends MiniClientPlugin<HubClient> implements IChatMess
_hologramManager = hologramManager;
new EasterEggHunt(plugin, _clientManager);
_questManager = new QuestManager(hologramManager, null, _inventoryManager, _donationManager);
new TemporaryGemHuntersServerSender(_portal);
@ -1029,4 +1033,9 @@ public class HubManager extends MiniClientPlugin<HubClient> implements IChatMess
{
return _jumpManager;
}
public QuestManager getQuestManager()
{
return _questManager;
}
}

View File

@ -0,0 +1,78 @@
package mineplex.hub.brawl.fountain;
import java.util.Calendar;
import java.util.TimeZone;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.common.util.F;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.hub.server.ServerManager;
public class FountainManager extends MiniPlugin
{
private final ServerManager _serverManager;
private boolean _brawlActive = false;
public FountainManager(JavaPlugin plugin, ServerManager serverManager)
{
super("Counter", plugin);
_serverManager = serverManager;
}
@EventHandler
public void updateFountainCount(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
return;
updateBrawlActive();
}
public void updateBrawlActive()
{
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("PST"));
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
_brawlActive = dayOfWeek == Calendar.FRIDAY || dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY;
}
@EventHandler
public void onInteractAtEntity(PlayerInteractAtEntityEvent event)
{
tryBrawl(event.getPlayer(), event.getRightClicked());
}
@EventHandler
public void onDamage(EntityDamageByEntityEvent event)
{
if (event.getDamager() instanceof Player)
{
tryBrawl((Player) event.getDamager(), event.getEntity());
}
}
private void tryBrawl(Player player, Entity entity)
{
if (entity.getCustomName() != null && entity.isCustomNameVisible())
{
if (entity.getCustomName().contains("Weekend Brawl"))
{
if (_brawlActive)
{
_serverManager.getBrawlShop().attemptShopOpen(player);
}
else
{
player.sendMessage(F.main("BRAWL", "Come back this weekend to play Weekend Brawl!"));
}
}
}
}
}

View File

@ -29,7 +29,6 @@ import mineplex.core.Managers;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.boosters.BoosterManager;
import mineplex.core.brawl.fountain.BrawlShopProvider;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.Callback;
@ -62,7 +61,7 @@ import mineplex.serverdata.Region;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.data.ServerGroup;
public class ServerManager extends MiniPlugin implements BrawlShopProvider
public class ServerManager extends MiniPlugin
{
private static final Long FREE_PORTAL_TIMER = -1L;
private static final Long BETA_PORTAL_TIMER = 120000L;
@ -858,7 +857,7 @@ public class ServerManager extends MiniPlugin implements BrawlShopProvider
public ShopBase<ServerManager> getBrawlShop()
{
return _serverNpcShopMap.get("Weekend Brawl");
return _serverNpcShopMap.get("BRAWL");
}
public ShopBase<ServerManager> getBawkShop()

View File

@ -44,6 +44,7 @@ public enum GameType
MineWare("MineWare"),
MinecraftLeague("MCL"),
MilkCow("Milk the Cow"),
HOG("Heroes of GWEN"),
MonsterLeague("MonsterLeague"),
MonsterMaze("Monster Maze"),
Paintball("Super Paintball"),

View File

@ -100,7 +100,7 @@ public class CustomDamageEvent extends Event implements Cancellable
public void AddMod(String source, double mod)
{
AddMod(source, new String(), mod, false);
AddMod(source, "", mod, false);
}
public void AddMod(String source, String reason, double mod, boolean useAttackName)

View File

@ -8,6 +8,10 @@
<artifactId>mineplex-parent</artifactId>
<version>dev-SNAPSHOT</version>
</parent>
<properties>
<version.guava>18.0</version.guava>
</properties>
<artifactId>mineplex-serverdata</artifactId>
@ -33,5 +37,11 @@
<artifactId>jooq</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${version.guava}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,356 @@
package mineplex.serverdata.redis.messaging;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import mineplex.serverdata.Utility;
import mineplex.serverdata.servers.ConnectionData;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;
/**
* A subscription to a Redis pub/sub system through a Jedis client. Includes a publishing mechanism
* as well.
* <p>
* Subscribes to Jedis and offers a variety of methods to edit the channels that this listens to
* over time. Does not support pattern-matching, even though Jedis can. Takes a single subscriber to
* inform of incoming messages (on all channels this is subscribed to).
* <p>
* For the sake of internal efficiency, this does not protect the sanity or unchangeability of
* arguments passed into its methods. Clients should not generally interact with this directly.
* <p>
* The Jedis pub/sub interface is a little confusing, especially when it comes to multithreading. At
* any given time, if this class is subscribed to any channels at all, it will have a single thread
* that is listening for incoming messages from redis with a blocking method. After that listening
* thread is created, we can add and remove subscriptions as desired, but the initial subscription
* and actual listening must be done on its own thread. When all channels are unsubscribed from, the
* listening thread returns. Note that this is stated with about 70% certainty, as the internals of
* the pub/sub mechanism are not entirely clear to me.
* <p>
* This class maintains a constant connection to its redis server by subscribing to a base channel.
* This makes it much easier to protect its operation from potentially insane client commands.
* <p>
* If the connection to the given redis instance fails or is interrupted, will keep attempting to
* reconnect periodically until destroyed. Publishers and subscribers are not informed of failure in
* any way.
* <p>
* When {@link #unsubscribe()} or {@link #destroy()} is called, this class ceases operation.
*/
public class PubSubJedisClient extends JedisPubSub implements PubSubLibraryClient
{
private static final long RECONNECT_PERIOD_MILLIS = 800;
private static final String BASE_CHANNEL = "pG8n5jp#";
private static final String BOLD = "\u001B[1m";
private static final String RESET = "\u001B[0m";
private final String _id;
private JedisPool _writePool;
private final ConnectionData _readConn;
private JedisPool _readPool;
private final ExecutorService _threadPool = Executors.newCachedThreadPool();
private volatile Subscriber _sub;
private final Set<String> _channels = Collections
.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
private final Map<String, SettableFuture<Boolean>> _pendingFutures = new ConcurrentHashMap<String, SettableFuture<Boolean>>();
private volatile boolean _subscribed; // Is there a base subscription yet?
private volatile boolean _destroyed; // has this been deliberately destroyed?
/**
* Class constructor.
*
* @param writeTo The connection info for the redis instance this client should publish to.
* @param readFrom The connection info for the redis instance this client to subscribe to.
*/
public PubSubJedisClient(ConnectionData writeTo, ConnectionData readFrom)
{
if (writeTo == null)
{
throw new IllegalArgumentException("redis connection info cannot be null");
}
_id = writeTo.getName();
_writePool = Utility.generatePool(writeTo);
_readConn = readFrom;
_readPool = Utility.generatePool(readFrom);
createSubscription(BASE_CHANNEL);
}
@Override
public final synchronized void setSubscriber(Subscriber sub)
{
_sub = sub;
}
@Override
public final ListenableFuture<Boolean> addChannel(String channel)
{
SettableFuture<Boolean> ret = _pendingFutures.get(channel);
if (ret == null)
{
ret = SettableFuture.create();
_pendingFutures.put(channel, ret);
}
try
{
_channels.add(channel);
if (_subscribed)
{ // Already has a subscription thread and can just add a new channel to it.
subscribe(channel);
}
} catch (Exception ex)
{
log("Encountered issue subscribing to a channel.");
ex.printStackTrace();
ret.setException(ex);
}
return ret;
}
@Override
public final void removeChannel(String channel)
{
if (BASE_CHANNEL.equals(channel))
{ // Protects the base subscription
return;
}
_channels.remove(channel);
if (_subscribed)
{
unsubscribe(channel);
}
}
@Override
public final void unsubscribe()
{
destroy();
}
@Override
public final void destroy()
{
_destroyed = true;
try
{
super.unsubscribe();
} catch (NullPointerException e)
{
}
for (SettableFuture<Boolean> fut : _pendingFutures.values())
{
fut.set(false);
}
}
@Override
public final void onMessage(String channel, String message)
{
if (_sub == null || BASE_CHANNEL.equals(channel))
{
return;
}
try
{
_sub.onMessage(channel, message);
} catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public final ListenableFuture<Boolean> publish(final String channel, final String message)
{
final SettableFuture<Boolean> ret = SettableFuture.create();
_threadPool.execute(new Runnable()
{
@Override
public void run()
{
Jedis bJedis = null;
try
{
bJedis = _writePool.getResource();
bJedis.publish(channel, message);
_writePool.returnResource((Jedis) bJedis);
ret.set(true);
} catch (Exception e)
{
log("Encountered issue while publishing a message.");
e.printStackTrace();
if (bJedis != null)
{
_writePool.returnBrokenResource((Jedis) bJedis);
}
ret.set(false);
}
}
});
return ret;
}
// Confirms successful subscriptions/unsubscriptions.
@Override
public void onSubscribe(String channel, int subscribedChannels)
{
// informs subscriber that this subscription completed successfully
SettableFuture<Boolean> fut = _pendingFutures.remove(channel);
if (fut != null)
{
fut.set(true);
}
if (!_subscribed)
{
for (String subscribeTo : _channels)
{
subscribe(subscribeTo);
}
}
_subscribed = true;
log("Subscribed to channel: " + channel);
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels)
{
log("Unsubscribed from channel: " + channel);
}
/**
* Creates the initial listening thread which blocks as it polls redis for new messages.
* Subsequent subscriptions can simply be added using {@link #subscribe(String...)} after the
* subscription thread has been created.
*
* @param firstChannel The first channel to initially subscribe to. If you do not have a first
* channel, there is no reason to create a subscriber thread yet.
*/
private void createSubscription(final String firstChannel)
{
final JedisPubSub pubsub = this;
new Thread(new Runnable()
{
@Override
public void run()
{
boolean first = true;
while (!_destroyed)
{
if (!first)
{
log("Jedis connection to " + _readConn.getHost() + ":"
+ _readConn.getPort()
+ " failed or was interrupted, attempting to reconnect");
}
first = false;
Jedis jedisInstance = null;
try
{
// gets a non-thread-safe jedis instance from the thread-safe pool.
jedisInstance = _readPool.getResource();
log("Creating initial jedis subscription to channel " + firstChannel);
// this will block as long as there are subscriptions
jedisInstance.subscribe(pubsub, firstChannel);
log("jedisInstance.subscribe() returned, subscription over.");
// when the subscription ends (subscribe() returns), returns the instance to
// the pool
_readPool.returnResource(jedisInstance);
} catch (JedisConnectionException e)
{
log("Jedis connection encountered an issue.");
e.printStackTrace();
if (jedisInstance != null)
{
_readPool.returnBrokenResource((Jedis) jedisInstance);
}
} catch (JedisDataException e)
{
log("Jedis connection encountered an issue.");
e.printStackTrace();
if (jedisInstance != null)
{
_readPool.returnBrokenResource((Jedis) jedisInstance);
}
}
_subscribed = false;
// sleeps for a short pause, rather than constantly retrying connection
if (!_destroyed)
{
try
{
Thread.sleep(RECONNECT_PERIOD_MILLIS);
} catch (InterruptedException e)
{
_destroyed = true;
log("Reconnection pause thread was interrupted.");
e.printStackTrace();
}
}
}
}
}).start();
}
// This implementation does not support pattern-matching subscriptions
@Override
public void onPMessage(String pattern, String channel, String message)
{
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels)
{
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels)
{
}
private void log(String msg)
{
System.out.println(BOLD + "[" + getClass().getSimpleName()
+ (_id != null && !_id.isEmpty() ? " " + _id : "") + "] " + RESET + msg);
}
}

View File

@ -0,0 +1,61 @@
package mineplex.serverdata.redis.messaging;
import com.google.common.util.concurrent.ListenableFuture;
/**
* A multi-channel subscription and publisher to a pub/sub messaging implementation. An interface to
* the actual low-level pub/sub library, whatever it may be.
*
* For the sake of internal efficiency, this makes no guarantees for the sanity or unchangeability
* of arguments passed into its methods. Clients should not generally interact with this directly.
*/
public interface PubSubLibraryClient
{
/**
* Publishes a message to all subscribers of a given channel.
*
* @param channel The channel to publish the message on.
* @param message The message to send.
* @return A future object that will complete after an unknown amount of time with
* <code>false</code> if for some locally known reason the message definitely could not
* be published, else completes with <code>true</code>.
*/
ListenableFuture<Boolean> publish(String channel, String message);
/**
* Adds a channel to this subscription.
*
* @param channel The channel to add. Should not change after being passed in.
* @return The asynchronous, future result of this attempt to add the channel. Will have
* <code>true</code> when the subscription starts successfully.
*/
ListenableFuture<Boolean> addChannel(String channel);
/**
* Removes a channel from this subscription.
*
* @param channel The channel to remove. Should not change after being passed in.
*/
void removeChannel(String channel);
/**
* Removes all channels from this subscription, kills its connections, and relinquishes any
* resources it was occupying.
* <p>
* Depending on the implementation, once a subscription has been destroyed, it may not be
* reusable and it may be necessary to construct a new one in order to resume.
* <p>
* Call this when the subscription is no longer being used. Holding unnecessary connections can
* cause serious performance and other issues on both ends.
*/
void destroy();
/**
* Sets the subscriber to inform of messages received by this subscription.
*
* @param sub The listener for this subscription.
*/
void setSubscriber(Subscriber sub);
}

View File

@ -0,0 +1,56 @@
package mineplex.serverdata.redis.messaging;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Messager for standard pub/sub model. Handles multiple publishers and subscribers.
* <p>
* All messaging is asynchronous and non-blocking, even to local subscribers.
* <p>
* For more about the pub/sub messaging paradigm, see <a
* href="http://en.wikipedia.org/wiki/Publish%E2
* %80%93subscribe_pattern">http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern</a>
*/
public interface PubSubMessager
{
/**
* Publishes a message to all subscribers of a given channel.
* <p>
* Publishes to all connected subscribers, including local ones.
*
* @param channel The channel to publish the message on.
* @param message The message to send.
* @return A future object that will complete after an unknown amount of time with
* <code>false</code> if for some locally known reason the message definitely could not
* be published, else completes with <code>true</code> (which does not guarantee it
* succeeded 100%).
*/
ListenableFuture<Boolean> publish(String channel, String message);
/**
* Subscribes to a messaging channel.
* <p>
* When incoming messages arrive, the subscriber is called from an arbitrary new thread.
*
* @param channel The channel to subscribe to.
* @param sub The subscriber to inform of incoming messages.
* @return The asynchronous, future result of this attempt to subscribe to the channel. Will
* have <code>true</code> when the subscription starts successfully.
*/
ListenableFuture<Boolean> subscribe(String channel, Subscriber sub);
/**
* Unsubscribes from a messaging channel.
*
* @param channel The channel to unsubscribe from.
* @param sub The subscriber to stop informing of incoming messages.
*/
void unsubscribe(String channel, Subscriber sub);
/**
* Attempts to gracefully shut down this messager. Generally irreversible.
*/
void shutdown();
}

View File

@ -0,0 +1,165 @@
package mineplex.serverdata.redis.messaging;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
/**
* A pub/sub messager that simply routes messages to some underlying pub/sub implementation, which
* is in turn represented by a multi-channel subscription and a publishing mechanism.
* <p>
* This class handles:
* <ol>
* <li>Providing a modular messaging interface that is thread-safe.
* <li>Protecting pub/sub implementations from some bad client behavior/data.
* <li>Routing messages for multiple subscribers to the same channel(s).
* </ol>
*/
public class PubSubRouter implements PubSubMessager, Subscriber
{
private final PubSubLibraryClient _pubSubClient;
private final Map<String, Set<Subscriber>> _subscribers;
private final ExecutorService _threadPool;
public PubSubRouter(PubSubLibraryClient client)
{
if (client == null)
{
throw new IllegalArgumentException("pubsub client cannot be null");
}
this._pubSubClient = client;
this._pubSubClient.setSubscriber(this);
this._subscribers = new ConcurrentHashMap<String, Set<Subscriber>>();
this._threadPool = Executors.newCachedThreadPool();
}
@Override
public final ListenableFuture<Boolean> publish(String channel, String message)
{
if (channel == null || channel.isEmpty())
{
throw new IllegalArgumentException("channel cannot be null or empty");
}
// messages of 0 length are allowed. Null messages are treated as messages of 0 length.
if (message == null)
{
message = "";
}
return _pubSubClient.publish(channel, message);
}
@Override
public final ListenableFuture<Boolean> subscribe(String channel, Subscriber sub)
{
if (channel == null || channel.isEmpty() || sub == null)
{
throw new IllegalArgumentException("params cannot be null and channel cannot be empty");
}
ListenableFuture<Boolean> ret = null;
Set<Subscriber> channelSubs = _subscribers.get(channel);
if (channelSubs == null)
{
// uses CopyOnWriteArraySet for fast and consistent iteration (forwarding messages to
// subscribers) but slow writes (adding/removing subscribers).
// See a discussion of the issue here:
// http://stackoverflow.com/questions/6720396/different-types-of-thread-safe-sets-in-java
channelSubs = new CopyOnWriteArraySet<Subscriber>();
_subscribers.put(channel, channelSubs);
// starts a jedis subscription to the channel if there were no subscribers before
ret = _pubSubClient.addChannel(channel);
} else
{
ret = SettableFuture.create();
((SettableFuture<Boolean>) ret).set(true); // already subscribed, calls back immediately
}
channelSubs.add(sub);
return ret;
}
@Override
public final void unsubscribe(String channel, Subscriber sub)
{
if (channel == null || channel.isEmpty() || sub == null)
{
throw new IllegalArgumentException("params cannot be null and channel cannot be empty");
}
Set<Subscriber> channelSubs = _subscribers.get(channel);
if (channelSubs == null)
{ // no subscribers for the channel to begin with.
return;
}
channelSubs.remove(sub);
// stops the subscription to this channel if the unsubscribed was the last subscriber
if (channelSubs.isEmpty())
{
_subscribers.remove(channel);
_pubSubClient.removeChannel(channel);
}
}
@Override
public final void onMessage(final String channel, final String message)
{
if (channel == null || message == null || channel.isEmpty())
{
return;
}
Set<Subscriber> channelSubs = _subscribers.get(channel);
if (channelSubs == null)
{ // We should not still be listening
_pubSubClient.removeChannel(channel);
return;
} else if (channelSubs.isEmpty())
{
_subscribers.remove(channel);
_pubSubClient.removeChannel(channel);
return;
}
for (final Subscriber sub : channelSubs)
{
// Gives subscribers their own thread from the thread pool in which to react to the
// message.
// Avoids interruptions and other problems while iterating over the subscriber set.
_threadPool.execute(new Runnable()
{
@Override
public void run()
{
sub.onMessage(channel, message);
}
});
}
}
@Override
public void shutdown()
{
_pubSubClient.destroy();
}
}

View File

@ -0,0 +1,19 @@
package mineplex.serverdata.redis.messaging;
/**
* A subscriber to a pub/sub channel.
*/
public interface Subscriber
{
/**
* Called when a message is sent on a channel that this is subscribed to.
* <p>
* No guarantees are made about what thread this will be called from.
*
* @param channel The channel that the message was sent on.
* @param message The message that was received.
*/
void onMessage(String channel, String message);
}

View File

@ -6,7 +6,6 @@ import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
@ -54,7 +53,6 @@ public class CustomerSupport extends MiniPlugin implements ResultSetCallable
private CustomerSupportRepository _repository;
private PowerPlayClubRepository _powerPlayRepo;
private NautHashMap<Player, HashSet<String>> _agentCacheMap = new NautHashMap<Player, HashSet<String>>();
private NautHashMap<Integer, List<String>> _accountBonusLog = new NautHashMap<>();
private boolean _allowWeatherChange = false;
@ -72,6 +70,10 @@ public class CustomerSupport extends MiniPlugin implements ResultSetCallable
_allowWeatherChange = true;
Bukkit.getWorlds().get(0).setStorm(false);
_allowWeatherChange = false;
addCommand(new checkCommand(this));
addCommand(new checkOwnsPackageCommand(this));
addCommand(new ListPPCCommand(this, _powerPlayRepo));
}
@EventHandler
@ -100,27 +102,12 @@ public class CustomerSupport extends MiniPlugin implements ResultSetCallable
event.setFormat(C.cGold + "%1$s " + C.cWhite + "%2$s");
}
@Override
public void addCommands()
{
addCommand(new checkCommand(this));
addCommand(new checkOwnsPackageCommand(this));
}
public void Help(Player caller)
{
caller.sendMessage(F.main(getName(), "Usage : /check defek7"));
}
public void addAgentMapping(Player caller, CoreClient client)
{
if (!_agentCacheMap.containsKey(caller))
_agentCacheMap.put(caller, new HashSet<String>());
_agentCacheMap.get(caller).add(client.getName());
}
public void showPlayerInfo(Player caller, CoreClient client)
{
String playerName = client.getName();
@ -473,12 +460,6 @@ public class CustomerSupport extends MiniPlugin implements ResultSetCallable
event.setCancelled(true);
}
@EventHandler
public void removeMapping(PlayerQuitEvent event)
{
_agentCacheMap.remove(event.getPlayer());
}
@EventHandler
public void foodLevelChange(FoodLevelChangeEvent event)
{

View File

@ -0,0 +1,117 @@
package mineplex.staffServer.customerSupport;
import java.time.YearMonth;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
import mineplex.core.powerplayclub.PowerPlayClubRewards;
import mineplex.core.powerplayclub.PowerPlayData;
public class ListPPCCommand extends CommandBase<CustomerSupport>
{
private final PowerPlayClubRepository _powerPlayRepo;
public ListPPCCommand(CustomerSupport customerSupport, PowerPlayClubRepository powerPlayRepo)
{
super(customerSupport, Rank.MODERATOR, "listppc", "checkppc");
_powerPlayRepo = powerPlayRepo;
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage: /" + _aliasUsed + " <Player>"));
return;
}
_commandCenter.GetClientManager().checkPlayerName(caller, args[0], name ->
{
if (name != null)
{
_commandCenter.GetClientManager().loadClientByName(name, client ->
{
if (client == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "Could not load data for " + name));
return;
}
PowerPlayData powerPlayData = _powerPlayRepo.loadData(client.getAccountId()).join();
Inventory inventory = buildPPCDisplay(client.getName(), powerPlayData);
caller.openInventory(inventory);
});
}
});
}
private static Inventory buildPPCDisplay(String playerName, PowerPlayData data)
{
Inventory result = Bukkit.createInventory(null, Math.max(1, (int)Math.ceil(data.getSubscriptions().size() / 9D)) * 9, playerName + "'s Subscriptions");
data.getSubscriptions().stream().map(sub -> buildSubDisplay(data, sub)).forEach(result::addItem);
return result;
}
private static ItemStack buildSubDisplay(PowerPlayData data, PowerPlayData.Subscription sub)
{
PowerPlayData dataForSubscription = PowerPlayData.fromSubsAndClaims(Collections.singletonList(sub), Collections.emptyList());
dataForSubscription.getUnclaimedMonths().removeIf(yearMonth -> !data.getUnclaimedMonths().contains(yearMonth));
boolean claimed = dataForSubscription.getUnclaimedMonths().isEmpty();
List<String> lore = new ArrayList<>();
lore.add(C.cYellow + "Start date: " + C.cWhite + sub._startDate.getMonth().getDisplayName(TextStyle.SHORT, Locale.US) + " " + sub._startDate.getDayOfMonth() + " " + sub._startDate.getYear());
lore.add(C.cYellow + "Duration: " + C.cWhite + sub._duration.name());
lore.add(" ");
lore.add(C.cGreen + "Subscription Cosmetics");
PowerPlayClubRewards.rewards().entrySet().stream()
.filter(entry -> dataForSubscription.getUsableCosmeticMonths().contains(entry.getKey()))
.sorted(Comparator.comparing(Map.Entry::getKey))
.forEach(entry ->
{
YearMonth yearMonth = entry.getKey();
lore.add(C.cWhite + " " + entry.getValue().getPrizeName() + " " + C.cGold + yearMonth.getMonth().getDisplayName(TextStyle.SHORT, Locale.US) + " " + yearMonth.getYear());
});
lore.add(" ");
if (claimed)
{
lore.add(C.cYellow + "All current rewards claimed");
}
else
{
lore.add(C.cRed + "Unclaimed rewards");
lore.add(" " + C.cWhite + (PowerPlayClubRewards.AMPLIFIERS_PER_MONTH * dataForSubscription.getUnclaimedMonths().size()) + " Game Amplifier");
lore.add(" " + C.cWhite + (PowerPlayClubRewards.CHESTS_PER_MONTH * dataForSubscription.getUnclaimedMonths().size()) + " Omega Chest");
}
ItemStack stack = new ItemStack(claimed ? Material.IRON_BLOCK : Material.GOLD_BLOCK);
ItemMeta meta = stack.getItemMeta();
meta.setDisplayName(C.cWhite + "Subscription");
meta.setLore(lore);
stack.setItemMeta(meta);
return stack;
}
}

View File

@ -1,12 +1,11 @@
package mineplex.staffServer.customerSupport;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
public class checkCommand extends CommandBase<CustomerSupport>
{
@ -35,7 +34,6 @@ public class checkCommand extends CommandBase<CustomerSupport>
if (client != null)
{
Plugin.showPlayerInfo(caller, client);
Plugin.addAgentMapping(caller, client);
}
else
{

View File

@ -394,4 +394,9 @@ public class Arcade extends JavaPlugin
config.GameModeMods.get(mode).put(var, value);
}
}
public ServerConfiguration getServerConfig()
{
return _serverConfiguration;
}
}

View File

@ -94,6 +94,7 @@ import mineplex.core.preferences.PreferencesManager;
import mineplex.core.progression.KitProgressionManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.punish.Punish;
import mineplex.core.quests.QuestManager;
import mineplex.core.rankGiveaway.eternal.EternalGiveawayManager;
import mineplex.core.rankGiveaway.titangiveaway.TitanGiveawayManager;
import mineplex.core.resourcepack.ResourcePackManager;
@ -233,8 +234,8 @@ public class ArcadeManager extends MiniPlugin implements IRelation
private ScoreboardManager _scoreboardManager;
private NextBestGameManager _nextBestGameManager;
private TrackManager _trackManager;
private QuestManager _questManager;
private GoogleSheetsManager _sheetsManager;
private IncognitoManager _incognitoManager;
private TaskManager _taskManager;
@ -390,6 +391,7 @@ public class ArcadeManager extends MiniPlugin implements IRelation
_kitProgressionManager = new KitProgressionManager(getPlugin(), donationManager, clientManager);
_progressionKitManager = new ProgressingKitManager(this);
_serverUptimeManager = new ServerUptimeManager(this);
_questManager = new QuestManager(hologramManager, _gameLobbyManager.getMissions(), _inventoryManager, _donationManager);
if (GetHost() != null && !GetHost().isEmpty() && !GetHost().startsWith("COM-"))
{
@ -417,6 +419,11 @@ public class ArcadeManager extends MiniPlugin implements IRelation
@Override
public void handlePlayerJoin(String playerName)
{
if (GetGame() != null && GetGame().GetState() != GameState.Loading && GetGame().GetState() != GameState.Recruit && GetGame().UseCustomScoreboard)
{
return;
}
CoreClient client = GetClients().Get(playerName);
for (MineplexScoreboard scoreboard : getScoreboards().values())
@ -1223,6 +1230,7 @@ public class ArcadeManager extends MiniPlugin implements IRelation
player.setGameMode(GameMode.SURVIVAL);
player.setAllowFlight(false);
player.setFlySpeed(0.1F);
player.setWalkSpeed(0.2F);
UtilInv.Clear(player);
@ -2067,16 +2075,21 @@ public class ArcadeManager extends MiniPlugin implements IRelation
public TrackManager getTrackManager()
{
return this._trackManager;
return _trackManager;
}
public Titles getTitles()
{
return this._titles;
return _titles;
}
public QuestManager getQuestManager()
{
return _questManager;
}
public GoogleSheetsManager getSheetsManager()
{
return _sheetsManager;
}
}
}

View File

@ -1,14 +1,11 @@
package nautilus.game.arcade;
import nautilus.game.arcade.game.games.alieninvasion.AlienInvasion;
import nautilus.game.arcade.game.games.smash.SuperSmashTraining;
import org.bukkit.Material;
import mineplex.core.common.MinecraftVersion;
import mineplex.core.common.Pair;
import mineplex.core.game.GameCategory;
import mineplex.core.game.GameDisplay;
import nautilus.game.arcade.game.Game;
import nautilus.game.arcade.game.games.alieninvasion.AlienInvasion;
import nautilus.game.arcade.game.games.baconbrawl.BaconBrawl;
import nautilus.game.arcade.game.games.barbarians.Barbarians;
import nautilus.game.arcade.game.games.basketball.Basketball;
@ -65,6 +62,7 @@ import nautilus.game.arcade.game.games.minecraftleague.MinecraftLeague;
import nautilus.game.arcade.game.games.minestrike.Minestrike;
import nautilus.game.arcade.game.games.minestrike.modes.SuperPaintstrike;
import nautilus.game.arcade.game.games.mineware.BawkBawkBattles;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.monsterleague.MonsterLeague;
import nautilus.game.arcade.game.games.monstermaze.MonsterMaze;
import nautilus.game.arcade.game.games.oldmineware.OldMineWare;
@ -93,6 +91,7 @@ import nautilus.game.arcade.game.games.skywars.modes.SkySmash;
import nautilus.game.arcade.game.games.skywars.modes.UHCSkywars;
import nautilus.game.arcade.game.games.smash.SoloSuperSmash;
import nautilus.game.arcade.game.games.smash.SuperSmashDominate;
import nautilus.game.arcade.game.games.smash.SuperSmashTraining;
import nautilus.game.arcade.game.games.smash.TeamSuperSmash;
import nautilus.game.arcade.game.games.smash.modes.RandomKitSSM;
import nautilus.game.arcade.game.games.snake.Snake;
@ -124,6 +123,7 @@ import nautilus.game.arcade.game.games.valentines.Valentines;
import nautilus.game.arcade.game.games.wither.WitherGame;
import nautilus.game.arcade.game.games.wizards.Wizards;
import nautilus.game.arcade.game.games.zombiesurvival.ZombieSurvival;
import org.bukkit.Material;
public enum GameType
{
@ -232,6 +232,8 @@ public enum GameType
AlienInvasion(AlienInvasion.class, GameDisplay.AlienInvasion),
MOBA(Moba.class, GameDisplay.MOBA),
Event(EventGame.class, GameDisplay.Event, new GameType[]{
GameType.BaconBrawl, GameType.Barbarians, GameType.Bridge, GameType.Build, GameType.Build,
GameType.Cards, GameType.CastleSiege, GameType.ChampionsDominate, GameType.ChampionsTDM, GameType.Christmas,

View File

@ -0,0 +1,55 @@
package nautilus.game.arcade.events;
import java.util.ArrayList;
import org.bukkit.Location;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* ChestRefillEvent
*
* @author xXVevzZXx
*/
public class ChestRefillEvent extends Event implements Cancellable
{
private static final HandlerList handlers = new HandlerList();
private boolean _cancelled = false;
private ArrayList<Location> _chests;
public ChestRefillEvent(ArrayList<Location> chests)
{
_chests = (ArrayList<Location>) chests.clone();
}
public ArrayList<Location> getChests()
{
return _chests;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
@Override
public boolean isCancelled()
{
return _cancelled;
}
@Override
public void setCancelled(boolean cancelled)
{
_cancelled = cancelled;
}
}

View File

@ -18,6 +18,8 @@ import mineplex.core.lifetimes.ListenerComponent;
import mineplex.core.lifetimes.PhasedLifetime;
import mineplex.core.packethandler.IPacketHandler;
import mineplex.core.packethandler.PacketInfo;
import mineplex.core.quests.QuestManager;
import mineplex.core.quests.event.QuestInteractEvent;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.utils.UtilGameProfile;
@ -39,6 +41,14 @@ import nautilus.game.arcade.game.modules.Module;
import nautilus.game.arcade.kit.*;
import nautilus.game.arcade.managers.chat.ChatStatData;
import nautilus.game.arcade.managers.lobby.LobbyManager;
import nautilus.game.arcade.quest.ChestOpenQuestTracker;
import nautilus.game.arcade.quest.CollectQuestTracker;
import nautilus.game.arcade.quest.KillEntityQuestTracker;
import nautilus.game.arcade.quest.KillQuestTracker;
import nautilus.game.arcade.quest.ParticipateQuestTracker;
import nautilus.game.arcade.quest.PlayGameQuestTracker;
import nautilus.game.arcade.quest.QuestTracker;
import nautilus.game.arcade.quest.WinQuestTracker;
import nautilus.game.arcade.scoreboard.GameScoreboard;
import nautilus.game.arcade.stats.*;
import nautilus.game.arcade.wineffect.WinEffectManager;
@ -135,6 +145,7 @@ public abstract class Game extends ListenerComponent implements Lifetimed
// Scoreboard
protected GameScoreboard Scoreboard;
public boolean UseCustomScoreboard = false;
// Loaded from Map Config
public WorldData WorldData = null;
@ -217,7 +228,6 @@ public abstract class Game extends ListenerComponent implements Lifetimed
public int HealthSet = -1;
public boolean SpawnTeleport = true;
public boolean PrepareFreeze = true;
private double _itemMergeRadius = 0;
@ -253,7 +263,10 @@ public abstract class Game extends ListenerComponent implements Lifetimed
public boolean AllowParticles = true;
public boolean Prepare = true;
public long PrepareTime = 9000;
public boolean PrepareFreeze = true;
public boolean PrepareAutoAnnounce = true;
public boolean PlaySoundGameStart = true;
public double XpMult = 1;
@ -341,6 +354,7 @@ public abstract class Game extends ListenerComponent implements Lifetimed
private NautHashMap<String, Long> _deadBodiesExpire = new NautHashMap<String, Long>();
private final Set<StatTracker<? extends Game>> _statTrackers = new HashSet<>();
private final Set<QuestTracker<? extends Game>> _questTrackers = new HashSet<>();
private NautHashMap<Player, Player> _teamReqs = new NautHashMap<Player, Player>();
public WinEffectManager WinEffectManager = new WinEffectManager();
@ -413,6 +427,16 @@ public abstract class Game extends ListenerComponent implements Lifetimed
registerStatTrackers(new KillsStatTracker(this), new DeathsStatTracker(this), new AssistsStatTracker(this),
new ExperienceStatTracker(this), new WinStatTracker(this), new LoseStatTracker(this), new DamageDealtStatTracker(
this), new DamageTakenStatTracker(this), new GamesPlayedStatTracker(this));
// Quest Trackers
registerQuestTrackers(
new WinQuestTracker(this),
new KillQuestTracker(this),
new CollectQuestTracker(this),
new ChestOpenQuestTracker(this),
new KillEntityQuestTracker(this),
new PlayGameQuestTracker(this),
new ParticipateQuestTracker(this));
Manager.getResourcePackManager().setResourcePack(gameType.getResourcePackUrls(this), gameType.isEnforceResourcePack(this));
@ -1736,6 +1760,20 @@ public abstract class Game extends ListenerComponent implements Lifetimed
{
return _statTrackers;
}
public void registerQuestTrackers(QuestTracker<? extends Game>... questTrackers)
{
for (QuestTracker<? extends Game> tracker : questTrackers)
{
if (_questTrackers.add(tracker))
Bukkit.getPluginManager().registerEvents(tracker, Manager.getPlugin());
}
}
public Collection<QuestTracker<? extends Game>> getQuestTrackers()
{
return _questTrackers;
}
@EventHandler
public void onHangingBreak(HangingBreakEvent event)
@ -2010,6 +2048,13 @@ public abstract class Game extends ListenerComponent implements Lifetimed
((CraftEntity) event.getEntity()).getHandle().dead = false;
}
}
@EventHandler
public void onQuestBuy(QuestInteractEvent event)
{
if (GetState() == GameState.Live || GetState() == GameState.Prepare || GetState() == GameState.End)
event.setCancelled("You cant interact with " + QuestManager.QUEST_NAME + "s while you are ingame!");
}
public NautHashMap<String, Entity> getDeadBodies()
{
@ -2323,6 +2368,7 @@ public abstract class Game extends ListenerComponent implements Lifetimed
Managers.get(AntiHack.class).resetIgnoredChecks();
getLifetime().end();
getStatTrackers().forEach(HandlerList::unregisterAll);
getQuestTrackers().forEach(HandlerList::unregisterAll);
}
@EventHandler

View File

@ -1,71 +1,71 @@
package nautilus.game.arcade.game.games.castleassault.data;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.GameTeam;
public class CapturePoint
{
private static final int POINTS_TO_CAPTURE = 100;
private static final long TIME_PER_POINT = 1000;
private static final int POINTS_PER_TICK = 1;
private Location _loc;
private long _lastCap;
private int _points = 0;
private GameTeam _owner = null;
public CapturePoint(GameTeam owner, Location loc)
{
_owner = owner;
_loc = loc;
}
public int getMaxPoints()
{
return POINTS_TO_CAPTURE;
}
public int getPoints()
{
return _points;
}
public boolean isCaptured()
{
return _points >= POINTS_TO_CAPTURE;
}
public void update()
{
if (!UtilTime.elapsed(_lastCap, TIME_PER_POINT))
{
return;
}
int capping = 0;
for (Player player : UtilPlayer.getInRadius(_loc, 3.5).keySet())
{
if (UtilPlayer.isSpectator(player))
{
continue;
}
if (_owner.HasPlayer(player))
{
continue;
}
capping++;
}
if (capping > 0 && _points < POINTS_TO_CAPTURE)
{
_lastCap = System.currentTimeMillis();
_points += POINTS_PER_TICK;
}
}
package nautilus.game.arcade.game.games.castleassault.data;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.GameTeam;
public class CapturePoint
{
private static final int POINTS_TO_CAPTURE = 100;
private static final long TIME_PER_POINT = 1000;
private static final int POINTS_PER_TICK = 1;
private Location _loc;
private long _lastCap;
private int _points = 0;
private GameTeam _owner = null;
public CapturePoint(GameTeam owner, Location loc)
{
_owner = owner;
_loc = loc;
}
public int getMaxPoints()
{
return POINTS_TO_CAPTURE;
}
public int getPoints()
{
return _points;
}
public boolean isCaptured()
{
return _points >= POINTS_TO_CAPTURE;
}
public void update()
{
if (!UtilTime.elapsed(_lastCap, TIME_PER_POINT))
{
return;
}
int capping = 0;
for (Player player : UtilPlayer.getInRadius(_loc, 3.5).keySet())
{
if (UtilPlayer.isSpectator(player))
{
continue;
}
if (_owner.HasPlayer(player))
{
continue;
}
capping++;
}
if (capping > 0 && _points < POINTS_TO_CAPTURE)
{
_lastCap = System.currentTimeMillis();
_points += POINTS_PER_TICK;
}
}
}

View File

@ -1,47 +1,47 @@
package nautilus.game.arcade.game.games.castleassault.data;
public class KillStreakData
{
private static final int[] REWARDED_STREAKS = {2, 4, 6, 8};
private int _kills;
private int _bestStreak;
public KillStreakData()
{
_kills = 0;
_bestStreak = 0;
}
public int getKills()
{
return _kills;
}
public int getBestStreak()
{
return Math.max(_bestStreak, _kills);
}
public boolean addKill(boolean hardLine)
{
_kills++;
for (int streak : REWARDED_STREAKS)
{
if ((_kills + (hardLine ? 1 : 0)) == streak)
{
return true;
}
}
return false;
}
public void reset()
{
if (_kills > _bestStreak)
{
_bestStreak = _kills;
}
_kills = 0;
}
package nautilus.game.arcade.game.games.castleassault.data;
public class KillStreakData
{
private static final int[] REWARDED_STREAKS = {2, 4, 6, 8};
private int _kills;
private int _bestStreak;
public KillStreakData()
{
_kills = 0;
_bestStreak = 0;
}
public int getKills()
{
return _kills;
}
public int getBestStreak()
{
return Math.max(_bestStreak, _kills);
}
public boolean addKill(boolean hardLine)
{
_kills++;
for (int streak : REWARDED_STREAKS)
{
if ((_kills + (hardLine ? 1 : 0)) == streak)
{
return true;
}
}
return false;
}
public void reset()
{
if (_kills > _bestStreak)
{
_bestStreak = _kills;
}
_kills = 0;
}
}

View File

@ -1,100 +1,100 @@
package nautilus.game.arcade.game.games.castleassault.data;
import java.util.List;
import org.bukkit.Color;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime;
public class ObjectiveTNTSpawner
{
private static final long TNT_SPAWN_DELAY = 60000;
private List<Location> _locs;
private Location _lastSpawnLoc;
private Item _entity;
private long _lastPickedUp;
public ObjectiveTNTSpawner(List<Location> locs)
{
_locs = locs;
_lastSpawnLoc = null;
_entity = null;
_lastPickedUp = System.currentTimeMillis();
}
public Item getItem()
{
return _entity;
}
public boolean isSpawned()
{
return _entity != null;
}
public boolean canPlaceFireAt(Block block)
{
for (Location loc : _locs)
{
if (UtilMath.offsetSquared(loc, block.getLocation()) <= 9)
{
return false;
}
}
return true;
}
public long getNextTNT()
{
return (_lastPickedUp + TNT_SPAWN_DELAY) - System.currentTimeMillis();
}
public void spawn()
{
Location spawn = _locs.get(UtilMath.r(_locs.size()));
spawn.getBlock().getRelative(BlockFace.DOWN).setType(Material.REDSTONE_BLOCK);
_lastSpawnLoc = spawn.clone();
_entity = spawn.getWorld().dropItem(spawn, new ItemStack(Material.TNT));
UtilFirework.playFirework(spawn, Type.BURST, Color.RED, false, false);
}
public void pickup()
{
_entity.getLocation().getBlock().getRelative(BlockFace.DOWN).setType(Material.IRON_BLOCK);
_entity.remove();
_entity = null;
_lastSpawnLoc = null;
_lastPickedUp = System.currentTimeMillis();
}
public void update()
{
if (!isSpawned() && UtilTime.elapsed(_lastPickedUp, TNT_SPAWN_DELAY))
{
spawn();
}
else if (isSpawned())
{
_entity.teleport(_lastSpawnLoc);
if (!_entity.isValid() || _entity.isDead())
{
_entity = _lastSpawnLoc.getWorld().dropItem(_lastSpawnLoc, new ItemStack(Material.TNT));
}
}
}
public void onStart()
{
_lastPickedUp = System.currentTimeMillis();
}
package nautilus.game.arcade.game.games.castleassault.data;
import java.util.List;
import org.bukkit.Color;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime;
public class ObjectiveTNTSpawner
{
private static final long TNT_SPAWN_DELAY = 60000;
private List<Location> _locs;
private Location _lastSpawnLoc;
private Item _entity;
private long _lastPickedUp;
public ObjectiveTNTSpawner(List<Location> locs)
{
_locs = locs;
_lastSpawnLoc = null;
_entity = null;
_lastPickedUp = System.currentTimeMillis();
}
public Item getItem()
{
return _entity;
}
public boolean isSpawned()
{
return _entity != null;
}
public boolean canPlaceFireAt(Block block)
{
for (Location loc : _locs)
{
if (UtilMath.offsetSquared(loc, block.getLocation()) <= 9)
{
return false;
}
}
return true;
}
public long getNextTNT()
{
return (_lastPickedUp + TNT_SPAWN_DELAY) - System.currentTimeMillis();
}
public void spawn()
{
Location spawn = _locs.get(UtilMath.r(_locs.size()));
spawn.getBlock().getRelative(BlockFace.DOWN).setType(Material.REDSTONE_BLOCK);
_lastSpawnLoc = spawn.clone();
_entity = spawn.getWorld().dropItem(spawn, new ItemStack(Material.TNT));
UtilFirework.playFirework(spawn, Type.BURST, Color.RED, false, false);
}
public void pickup()
{
_entity.getLocation().getBlock().getRelative(BlockFace.DOWN).setType(Material.IRON_BLOCK);
_entity.remove();
_entity = null;
_lastSpawnLoc = null;
_lastPickedUp = System.currentTimeMillis();
}
public void update()
{
if (!isSpawned() && UtilTime.elapsed(_lastPickedUp, TNT_SPAWN_DELAY))
{
spawn();
}
else if (isSpawned())
{
_entity.teleport(_lastSpawnLoc);
if (!_entity.isValid() || _entity.isDead())
{
_entity = _lastSpawnLoc.getWorld().dropItem(_lastSpawnLoc, new ItemStack(Material.TNT));
}
}
}
public void onStart()
{
_lastPickedUp = System.currentTimeMillis();
}
}

View File

@ -1,54 +1,54 @@
package nautilus.game.arcade.game.games.castleassault.data;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.EnderCrystal;
import nautilus.game.arcade.game.GameTeam;
public class TeamCrystal
{
private Location _loc;
private GameTeam _owner;
private EnderCrystal _crystal;
private boolean _destroyed;
public TeamCrystal(GameTeam owner, Location loc)
{
_owner = owner;
_loc = loc;
spawn();
}
public GameTeam getOwner()
{
return _owner;
}
public Location getLocation()
{
return _loc;
}
public boolean isActive()
{
return !_destroyed;
}
public void spawn()
{
_destroyed = false;
_crystal = _loc.getWorld().spawn(_loc, EnderCrystal.class);
_loc.getBlock().getRelative(0, -2, 0).setType(Material.BEACON);
}
public void destroy()
{
_destroyed = true;
_crystal.remove();
_crystal = null;
_loc.getBlock().getRelative(0, -2, 0).setType(Material.SMOOTH_BRICK);
}
package nautilus.game.arcade.game.games.castleassault.data;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.EnderCrystal;
import nautilus.game.arcade.game.GameTeam;
public class TeamCrystal
{
private Location _loc;
private GameTeam _owner;
private EnderCrystal _crystal;
private boolean _destroyed;
public TeamCrystal(GameTeam owner, Location loc)
{
_owner = owner;
_loc = loc;
spawn();
}
public GameTeam getOwner()
{
return _owner;
}
public Location getLocation()
{
return _loc;
}
public boolean isActive()
{
return !_destroyed;
}
public void spawn()
{
_destroyed = false;
_crystal = _loc.getWorld().spawn(_loc, EnderCrystal.class);
_loc.getBlock().getRelative(0, -2, 0).setType(Material.BEACON);
}
public void destroy()
{
_destroyed = true;
_crystal.remove();
_crystal = null;
_loc.getBlock().getRelative(0, -2, 0).setType(Material.SMOOTH_BRICK);
}
}

View File

@ -125,4 +125,4 @@ public class TeamKing
return true;
}
}
}

View File

@ -14,6 +14,7 @@ import nautilus.game.arcade.game.games.champions.kits.KitBrute;
import nautilus.game.arcade.game.games.champions.kits.KitKnight;
import nautilus.game.arcade.game.games.champions.kits.KitMage;
import nautilus.game.arcade.game.games.champions.kits.KitRanger;
import nautilus.game.arcade.game.games.champions.quests.FlagQuestTracker;
import nautilus.game.arcade.game.games.common.CaptureTheFlag;
import nautilus.game.arcade.kit.Kit;
import nautilus.game.arcade.managers.chat.ChatStatData;
@ -83,6 +84,8 @@ public class ChampionsCTF extends CaptureTheFlag
new ClutchStatTracker(this, "Clutch"),
new SpecialWinStatTracker(this, "SpecialWin")
);
registerQuestTrackers(new FlagQuestTracker(this));
registerChatStats(
Kills,

View File

@ -14,6 +14,7 @@ import nautilus.game.arcade.game.games.champions.kits.KitBrute;
import nautilus.game.arcade.game.games.champions.kits.KitKnight;
import nautilus.game.arcade.game.games.champions.kits.KitMage;
import nautilus.game.arcade.game.games.champions.kits.KitRanger;
import nautilus.game.arcade.game.games.champions.quests.CaptureQuestTracker;
import nautilus.game.arcade.game.games.common.Domination;
import nautilus.game.arcade.kit.Kit;
import nautilus.game.arcade.stats.ElectrocutionStatTracker;
@ -77,6 +78,8 @@ public class ChampionsDominate extends Domination
new TheLongestShotStatTracker(this),
new SeismicSlamStatTracker(this)
);
registerQuestTrackers(new CaptureQuestTracker(this));
registerChatStats(
Kills,

View File

@ -0,0 +1,41 @@
package nautilus.game.arcade.game.games.champions.events;
import java.util.Collection;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* CaptureEvent
*
* @author xXVevzZXx
*/
public class CaptureEvent extends Event
{
private Collection<Player> _players;
public CaptureEvent(Collection<Player> players)
{
_players = players;
}
public Collection<Player> getPlayers()
{
return _players;
}
@Override
public HandlerList getHandlers()
{
return getHandlerList();
}
private static HandlerList _handlers = new HandlerList();
public static HandlerList getHandlerList()
{
return _handlers;
}
}

View File

@ -0,0 +1,32 @@
package nautilus.game.arcade.game.games.champions.quests;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.quests.TriggerType;
import nautilus.game.arcade.game.games.champions.ChampionsDominate;
import nautilus.game.arcade.game.games.champions.events.CaptureEvent;
import nautilus.game.arcade.quest.QuestTracker;
/**
* PointQuestTracker
*
* @author xXVevzZXx
*/
public class CaptureQuestTracker extends QuestTracker<ChampionsDominate>
{
public CaptureQuestTracker(ChampionsDominate game)
{
super(game, TriggerType.COLLECT);
}
@EventHandler
public void capture(CaptureEvent event)
{
for (Player player : event.getPlayers())
incrementQuests(player, 1, "Point Capture");
}
}

View File

@ -0,0 +1,30 @@
package nautilus.game.arcade.game.games.champions.quests;
import org.bukkit.event.EventHandler;
import mineplex.core.quests.TriggerType;
import nautilus.game.arcade.game.games.common.CaptureTheFlag;
import nautilus.game.arcade.game.games.common.ctf_data.PlayerCaptureFlagEvent;
import nautilus.game.arcade.quest.QuestTracker;
/**
* FlagQuestTracker
*
* @author xXVevzZXx
*/
public class FlagQuestTracker extends QuestTracker<CaptureTheFlag>
{
public FlagQuestTracker(CaptureTheFlag game)
{
super(game, TriggerType.COLLECT);
}
@EventHandler
public void captureFlag(PlayerCaptureFlagEvent event)
{
incrementQuests(event.GetPlayer(), 1, "Flag Capture");
}
}

View File

@ -7,9 +7,11 @@ import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTextMiddle;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.champions.events.CaptureEvent;
import nautilus.game.arcade.game.games.common.Domination;
import org.bukkit.ChatColor;
@ -303,6 +305,8 @@ public class CapturePoint
}
UtilTextMiddle.display(null, _owner.GetColor() + _owner.GetName() + " captured " + _name, 5, 40, 5);
UtilServer.CallEvent(new CaptureEvent(capturers));
}
}
//Count Down

View File

@ -52,6 +52,7 @@ import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.SoloGame;
import nautilus.game.arcade.game.games.GameScore;
import nautilus.game.arcade.game.games.draw.kits.KitArtist;
import nautilus.game.arcade.game.games.draw.quests.GuessQuestTracker;
import nautilus.game.arcade.game.games.draw.tools.Tool;
import nautilus.game.arcade.game.games.draw.tools.ToolCircle;
import nautilus.game.arcade.game.games.draw.tools.ToolLine;
@ -254,6 +255,8 @@ public class Draw extends SoloGame
new DrawGuessStatTracker(this)
);
registerQuestTrackers(new GuessQuestTracker(this));
registerChatStats(
new ChatStatData("TotalGuess", "Total Guesses", true),
new ChatStatData("PureLuck", "Lucky Guesses", true)

View File

@ -0,0 +1,36 @@
package nautilus.game.arcade.game.games.draw.quests;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import mineplex.core.quests.TriggerType;
import nautilus.game.arcade.game.Game.GameState;
import nautilus.game.arcade.game.games.draw.Draw;
import nautilus.game.arcade.game.games.draw.DrawGuessCorrectlyEvent;
import nautilus.game.arcade.quest.QuestTracker;
/**
* GuesQuestTracker
*
* @author xXVevzZXx
*/
public class GuessQuestTracker extends QuestTracker<Draw>
{
public GuessQuestTracker(Draw game)
{
super(game, TriggerType.COLLECT);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onDrawGuessCorrectly(DrawGuessCorrectlyEvent event)
{
if (getGame().GetState() != GameState.Live)
return;
if (System.currentTimeMillis() - event.getDrawRound().Time < 8000)
incrementQuests(event.getPlayer(), 1, "Guesses");
}
}

View File

@ -19,7 +19,7 @@ public class KitEnderman
// @Override
// protected void giveItems(Player player)
// {
// player.getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.IRON_SWORD));
// player.getInventory().addSkillItem(ItemStackFactory.Instance.CreateStack(Material.IRON_SWORD));
//
// player.getWorld().playSound(player.getLocation(), Sound.ENDERMAN_IDLE, 4f, 1f);
//

View File

@ -34,7 +34,7 @@ public class KitSkeleton
// player.getInventory().setLeggings(new ItemBuilder(Material.CHAINMAIL_LEGGINGS).build());
// player.getInventory().setBoots(new ItemBuilder(Material.IRON_BOOTS).build());
//
// player.getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.BOW));
// player.getInventory().addSkillItem(ItemStackFactory.Instance.CreateStack(Material.BOW));
//
// player.getWorld().playSound(player.getLocation(), Sound.SKELETON_IDLE, 4f, 1f);
//

View File

@ -42,9 +42,9 @@ public class KitJetpack extends ProgressingKit
@Override
public void GiveItems(Player player)
{
//player.getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.SHEARS, (byte)0, 1, "Block Cannon"));
//player.getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.BOW, (byte)0, 1, "Space Shooter"));
//player.getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.ARROW, (byte)0, 64, "Space Arrows"));
//player.getInventory().addSkillItem(ItemStackFactory.Instance.CreateStack(Material.SHEARS, (byte)0, 1, "Block Cannon"));
//player.getInventory().addSkillItem(ItemStackFactory.Instance.CreateStack(Material.BOW, (byte)0, 1, "Space Shooter"));
//player.getInventory().addSkillItem(ItemStackFactory.Instance.CreateStack(Material.ARROW, (byte)0, 64, "Space Arrows"));
player.getInventory().addItem(PLAYER_ITEMS);
player.getInventory().setArmorContents(PLAYER_ARMOR);
}

View File

@ -46,6 +46,7 @@ import nautilus.game.arcade.game.games.hideseek.kits.KitHiderSwapper;
import nautilus.game.arcade.game.games.hideseek.kits.KitSeekerLeaper;
import nautilus.game.arcade.game.games.hideseek.kits.KitSeekerRadar;
import nautilus.game.arcade.game.games.hideseek.kits.KitSeekerTNT;
import nautilus.game.arcade.game.games.hideseek.quests.DisguiseQuestTracker;
import nautilus.game.arcade.game.modules.compass.CompassModule;
import nautilus.game.arcade.kit.Kit;
import nautilus.game.arcade.kit.NullKit;
@ -348,6 +349,8 @@ public class HideSeek extends TeamGame
new HunterOfTheYearStatTracker(this),
new BadHiderStatTracker(this)
);
registerQuestTrackers(new DisguiseQuestTracker(this));
//Need ideas for this one
registerChatStats();

View File

@ -0,0 +1,34 @@
package nautilus.game.arcade.game.games.hideseek.quests;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import mineplex.core.quests.TriggerType;
import nautilus.game.arcade.game.Game;
import nautilus.game.arcade.game.games.hideseek.HideSeek;
import nautilus.game.arcade.quest.QuestTracker;
/**
* DisguiseQuestTracker
*
* @author xXVevzZXx
*/
public class DisguiseQuestTracker extends QuestTracker<HideSeek>
{
public DisguiseQuestTracker(HideSeek game)
{
super(game, TriggerType.COLLECT);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onChangeForm(HideSeek.PlayerChangeFormEvent event)
{
if (getGame().GetState() != Game.GameState.Live)
return;
incrementQuests(event.getPlayer(), 1, "Disguise");
}
}

View File

@ -1470,7 +1470,7 @@ public class MinecraftLeague extends RankedTeamGame
player.getInventory().setBoots(new ItemBuilder(Material.LEATHER_BOOTS).setColor(Color.BLUE).setUnbreakable(true).build());
player.getInventory().addItem(new ItemStack(Material.STONE_SWORD));
player.getInventory().addItem(new ItemStack(Material.STONE_PICKAXE));
//player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 5));
//player.getInventory().addSkillItem(new ItemStack(Material.COOKED_BEEF, 5));
_blockLock.put(player, new BlockProtection(this, player));
_noFall.add(player);
}
@ -1482,7 +1482,7 @@ public class MinecraftLeague extends RankedTeamGame
player.getInventory().setBoots(new ItemBuilder(Material.LEATHER_BOOTS).setColor(Color.RED).setUnbreakable(true).build());
player.getInventory().addItem(new ItemStack(Material.STONE_SWORD));
player.getInventory().addItem(new ItemStack(Material.STONE_PICKAXE));
//player.getInventory().addItem(new ItemStack(Material.COOKED_BEEF, 5));
//player.getInventory().addSkillItem(new ItemStack(Material.COOKED_BEEF, 5));
_blockLock.put(player, new BlockProtection(this, player));
_noFall.add(player);
}

View File

@ -1,50 +1,780 @@
package nautilus.game.arcade.game.games.moba;
import java.util.ArrayList;
import mineplex.core.Managers;
import mineplex.core.beta.BetaWhitelist;
import mineplex.core.common.Pair;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.disguise.disguises.DisguiseBase;
import mineplex.core.disguise.disguises.DisguisePlayer;
import mineplex.core.leaderboard.Leaderboard;
import mineplex.core.leaderboard.LeaderboardManager;
import mineplex.core.leaderboard.LeaderboardRepository.LeaderboardSQLType;
import mineplex.minecraft.game.core.combat.DeathMessageType;
import nautilus.game.arcade.ArcadeManager;
import nautilus.game.arcade.GameType;
import nautilus.game.arcade.events.GameStateChangeEvent;
import nautilus.game.arcade.events.PlayerPrepareTeleportEvent;
import nautilus.game.arcade.game.DebugCommand;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.TeamGame;
import nautilus.game.arcade.game.games.sheep.kits.*;
import nautilus.game.arcade.game.games.moba.boss.BossManager;
import nautilus.game.arcade.game.games.moba.boss.wither.WitherBoss;
import nautilus.game.arcade.game.games.moba.buff.BuffManager;
import nautilus.game.arcade.game.games.moba.fountain.MobaFountain;
import nautilus.game.arcade.game.games.moba.general.ArrowKBManager;
import nautilus.game.arcade.game.games.moba.general.BetaManager;
import nautilus.game.arcade.game.games.moba.general.EnderPearlManager;
import nautilus.game.arcade.game.games.moba.general.MobaDamageManager;
import nautilus.game.arcade.game.games.moba.gold.GoldManager;
import nautilus.game.arcade.game.games.moba.kit.HeroKit;
import nautilus.game.arcade.game.games.moba.kit.KitPlayer;
import nautilus.game.arcade.game.games.moba.kit.anath.HeroAnath;
import nautilus.game.arcade.game.games.moba.kit.bardolf.HeroBardolf;
import nautilus.game.arcade.game.games.moba.kit.biff.HeroBiff;
import nautilus.game.arcade.game.games.moba.kit.bob.HeroBob;
import nautilus.game.arcade.game.games.moba.kit.dana.HeroDana;
import nautilus.game.arcade.game.games.moba.kit.devon.HeroDevon;
import nautilus.game.arcade.game.games.moba.kit.hattori.HeroHattori;
import nautilus.game.arcade.game.games.moba.kit.hp.HPManager;
import nautilus.game.arcade.game.games.moba.kit.larissa.HeroLarissa;
import nautilus.game.arcade.game.games.moba.kit.rowena.HeroRowena;
import nautilus.game.arcade.game.games.moba.minion.MinionManager;
import nautilus.game.arcade.game.games.moba.prepare.PrepareManager;
import nautilus.game.arcade.game.games.moba.prepare.PrepareSelection;
import nautilus.game.arcade.game.games.moba.recall.Recall;
import nautilus.game.arcade.game.games.moba.shop.MobaShop;
import nautilus.game.arcade.game.games.moba.structure.point.CapturePointManager;
import nautilus.game.arcade.game.games.moba.structure.tower.TowerManager;
import nautilus.game.arcade.game.games.moba.util.MobaUtil;
import nautilus.game.arcade.game.modules.CustomScoreboardModule;
import nautilus.game.arcade.game.modules.compass.CompassModule;
import nautilus.game.arcade.kit.Kit;
import nautilus.game.arcade.kit.NullKit;
import nautilus.game.arcade.managers.lobby.current.NewGameLobbyManager;
import nautilus.game.arcade.scoreboard.GameScoreboard;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class Moba extends TeamGame
{
private ArrayList<String> _lastScoreboard = new ArrayList<String>();
public Moba(ArcadeManager manager)
private static final String[] DESCRIPTION = {
"..."
};
private static final long PREPARE_TIME = TimeUnit.MINUTES.toMillis(1);
private final HeroKit[] _kits;
private final Set<MobaPlayer> _playerData = new HashSet<>();
private final Set<Listener> _listeners = new HashSet<>();
private final MobaShop _shop;
private final GoldManager _goldManager;
private final BossManager _boss;
private final TowerManager _tower;
private final CapturePointManager _capturePoint;
private final ArrowKBManager _arrowKb;
private final BuffManager _buffs;
private BetaWhitelist _betaWhitelist;
public Moba(ArcadeManager manager)
{
super(manager, GameType.Sheep,
super(manager, GameType.MOBA, new Kit[]{new KitPlayer(manager)}, DESCRIPTION);
new Kit[]
{
new NullKit(manager)
},
_kits = new HeroKit[]{
new HeroHattori(Manager),
new HeroDevon(Manager),
new HeroAnath(Manager),
new HeroDana(Manager),
new HeroBiff(Manager),
new HeroLarissa(Manager),
new HeroBardolf(Manager),
new HeroRowena(Manager),
new HeroBob(Manager)
};
new String[]
{
"..."
});
AllowParticles = false;
DontAllowOverfill = true;
PrepareAutoAnnounce = false;
PrepareFreeze = false;
PrepareTime = PREPARE_TIME;
DeathOut = false;
DeathSpectateSecs = 12;
HungerSet = 20;
DamageFall = false;
this.DeathOut = false;
this.DeathSpectateSecs = 8;
this.HungerSet = 20;
manager.getCosmeticManager().setHideParticles(true);
manager.GetCreature().SetDisableCustomDrops(true);
registerChatStats();
// Instantiate managers
// Global managers
_shop = registerManager(new MobaShop(this));
_goldManager = registerManager(new GoldManager(this));
registerManager(new HPManager(this));
registerManager(new MobaDamageManager(this));
registerManager(new MobaFountain(this));
registerManager(new Recall(this));
// Pregame managers
registerManager(new PrepareManager(this));
registerManager(new PrepareSelection(this));
// Bosses
_boss = registerManager(new BossManager(this));
// Structures
_tower = registerManager(new TowerManager(this));
_capturePoint = registerManager(new CapturePointManager(this));
// Minions
registerManager(new MinionManager(this));
// Arrow Knockback
_arrowKb = registerManager(new ArrowKBManager(this));
// Ender Pearls
registerManager(new EnderPearlManager());
// Buffs
_buffs = registerManager(new BuffManager());
// Beta Message
registerManager(new BetaManager(this));
// Beta Whitelist
_betaWhitelist = Managers.get(BetaWhitelist.class);
if (_betaWhitelist == null)
{
_betaWhitelist = new BetaWhitelist(manager.GetClients(), manager.getBonusManager().getPowerPlayClubRepository());
}
else
{
_betaWhitelist.registerSelf();
}
new CompassModule()
.setGiveCompass(true)
.setGiveCompassToSpecs(true)
.setGiveCompassToAlive(false)
.register(this);
new CustomScoreboardModule()
.setSidebar((player, scoreboard) ->
{
GameState state = GetState();
switch (state)
{
case Prepare:
writePrepare(player, scoreboard);
break;
case Live:
writeLive(player, scoreboard);
break;
}
})
.setPrefix((perspective, subject) ->
{
if (!IsAlive(subject))
{
return C.cGray;
}
GameTeam team = GetTeam(subject);
return team.GetColor().toString();
})
.setSuffix((perspective, subject) ->
{
GameState state = GetState();
GameTeam perspectiveTeam = GetTeam(perspective);
GameTeam subjectTeam = GetTeam(subject);
if (!IsAlive(subject) || perspectiveTeam == null || subjectTeam == null)
{
return "";
}
MobaPlayer mobaPlayer = getMobaData(subject);
String suffix;
if (state == GameState.Prepare && !perspectiveTeam.equals(subjectTeam))
{
suffix = C.cYellow + " Unknown";
}
else if (mobaPlayer.getKit() == null)
{
suffix = C.cYellow + " Selecting";
}
else
{
suffix = mobaPlayer.getRole().getChatColor() + " " + mobaPlayer.getKit().GetName();
}
return suffix + C.Reset;
})
.setUnderNameObjective(C.cRed + "")
.setUnderName((perspective, subject) ->
(int) (Math.ceil(subject.getHealth() / 2D)))
.register(this);
registerDebugCommand(new DebugCommand("kit", Rank.ADMIN)
{
@Override
public void Execute(Player caller, String[] args)
{
StringBuilder builder = new StringBuilder();
for (String arg : args)
{
builder.append(arg).append(" ");
}
String kit = builder.toString().trim();
for (Kit kits : _kits)
{
if (kit.equalsIgnoreCase(kits.GetName()))
{
SetKit(caller, kits, true);
return;
}
}
caller.sendMessage(F.main("Kit", "Sorry that is not a kit!"));
}
});
}
private <T extends Listener> T registerManager(T listener)
{
_listeners.add(listener);
return listener;
}
@Override
public void ParseData()
public void ParseData()
{
// Register all "Managers"
_listeners.forEach(UtilServer::RegisterEvents);
// Make all spawns face the center of the map
for (List<Location> locations : WorldData.SpawnLocs.values())
{
locations.forEach(location -> location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, GetSpectatorLocation()))));
}
SpectatorSpawn = WorldData.GetCustomLocs("CENTER").get(0);
// Leaderboards
if (Manager.IsRewardStats())
{
if (Manager.GetLobby() instanceof NewGameLobbyManager)
{
Map<String, List<Location>> lobbyCustomLocs = ((NewGameLobbyManager) Manager.GetLobby()).getCustomLocs();
LeaderboardManager leaderboard = Managers.get(LeaderboardManager.class);
Pair<String, String> winPair = Pair.create("Win", "Wins");
Pair<String, String> killPair = Pair.create("Kill", "Kills");
Pair<String, String> goldPair = Pair.create("Gold", "Gold");
{
Location location = lobbyCustomLocs.get("TOP_DAILY_WINS").get(0);
leaderboard.registerLeaderboard("TOP_HOG_DAILY_WINS", new Leaderboard("Top Daily Wins", winPair, new String[]{GetName() + ".Wins"}, LeaderboardSQLType.DAILY, location, 10));
}
{
Location location = lobbyCustomLocs.get("TOP_DAILY_KILLS").get(0);
leaderboard.registerLeaderboard("TOP_HOG_DAILY_KILLS", new Leaderboard("Top Daily Kills", killPair, new String[]{GetName() + ".Kills"}, LeaderboardSQLType.DAILY, location, 10));
}
{
Location location = lobbyCustomLocs.get("TOP_DAILY_GOLD").get(0);
leaderboard.registerLeaderboard("TOP_HOG_DAILY_GOLD", new Leaderboard("Top Daily Gold Earned", goldPair, new String[]{GetName() + ".GoldEarned"}, LeaderboardSQLType.DAILY, location, 10));
}
{
Location location = lobbyCustomLocs.get("TOP_WINS").get(0);
leaderboard.registerLeaderboard("TOP_HOG_WINS", new Leaderboard("Top Wins", winPair, new String[]{GetName() + ".Wins"}, LeaderboardSQLType.ALL, location, 10));
}
{
Location location = lobbyCustomLocs.get("TOP_KILLS").get(0);
leaderboard.registerLeaderboard("TOP_HOG_KILLS", new Leaderboard("Top Kills", killPair, new String[]{GetName() + ".Kills"}, LeaderboardSQLType.ALL, location, 10));
}
{
Location location = lobbyCustomLocs.get("TOP_GOLD").get(0);
leaderboard.registerLeaderboard("TOP_HOG_GOLD", new Leaderboard("Top Gold Earned", goldPair, new String[]{GetName() + ".GoldEarned"}, LeaderboardSQLType.ALL, location, 10));
}
}
}
}
private void writePrepare(Player player, GameScoreboard scoreboard)
{
MobaPlayer mobaPlayer = getMobaData(player);
scoreboard.writeNewLine();
scoreboard.write(C.cYellowB + "Hero Selection");
scoreboard.write(UtilTime.MakeStr(GetStateTime() + PREPARE_TIME - System.currentTimeMillis()));
scoreboard.writeNewLine();
scoreboard.write(C.cYellowB + "Hero");
scoreboard.write((mobaPlayer == null || mobaPlayer.getKit() == null) ? "Unselected " : mobaPlayer.getKit().GetName() + " (" + mobaPlayer.getRole().getName() + ")");
scoreboard.writeNewLine();
scoreboard.write(C.cYellowB + "Players");
int kits = 0;
for (MobaPlayer otherMobaPlayer : _playerData)
{
if (otherMobaPlayer.getKit() != null)
{
kits++;
}
}
scoreboard.write(kits + "/" + GetPlayers(true).size());
scoreboard.writeNewLine();
}
private void writeLive(Player player, GameScoreboard scoreboard)
{
GameTeam team = GetTeam(player);
boolean alive = IsAlive(player);
scoreboard.writeNewLine();
// Towers
GameTeam red = GetTeam(ChatColor.RED);
GameTeam blue = GetTeam(ChatColor.AQUA);
String redTitle;
String blueTitle;
if (alive)
{
boolean playerRed = team.equals(red);
redTitle = playerRed ? "Your Team" : "Enemy Team";
blueTitle = playerRed ? "Enemy Team" : "Your Team";
}
else
{
redTitle = "Red Team";
blueTitle = "Blue Team";
}
scoreboard.write(red.GetColor() + C.Bold + redTitle);
scoreboard.write("Base: " + _tower.getDisplayString(red) + _boss.getWitherDisplayString(red));
scoreboard.writeNewLine();
scoreboard.write(blue.GetColor() + C.Bold + blueTitle);
scoreboard.write("Base: " + _tower.getDisplayString(blue) + _boss.getWitherDisplayString(blue));
scoreboard.writeNewLine();
scoreboard.write(C.cGreenB + "Beacons");
scoreboard.write(_capturePoint.getDisplayString());
scoreboard.writeNewLine();
// Gold
scoreboard.write(C.cGoldB + "Your Gold");
if (alive)
{
int gold = _goldManager.getGold(player);
scoreboard.write(String.valueOf(gold));
}
else
{
scoreboard.write("None");
}
scoreboard.writeNewLine();
scoreboard.write(C.cYellowB + "Time");
scoreboard.write(UtilTime.MakeStr(System.currentTimeMillis() - GetStateTime()));
}
@EventHandler(priority = EventPriority.LOWEST)
public void prepare(GameStateChangeEvent event)
{
if (event.GetState() != GameState.Prepare)
{
return;
}
// Override those kits!
setKits(_kits);
// Store player data
for (Player player : GetPlayers(true))
{
_playerData.add(new MobaPlayer(player));
MobaUtil.setTeamEntity(player, GetTeam(player));
}
}
@EventHandler
public void preventOverfill(PlayerPrepareTeleportEvent event)
{
Player player = event.GetPlayer();
if (GetPlayers(true).size() > 8)
{
SetPlayerState(player, GameTeam.PlayerState.OUT);
Manager.addSpectator(player, true);
player.sendMessage(F.main("Game", "Too many players are in this server. You are now spectating, sorry."));
}
}
@Override
public void EndCheck()
{
if (!IsLive())
{
return;
}
// Only one team online check
List<GameTeam> teamsWithPlayers = new ArrayList<>(GetTeamList().size());
for (GameTeam team : GetTeamList())
{
if (team.GetPlayers(true).isEmpty())
{
continue;
}
teamsWithPlayers.add(team);
}
if (teamsWithPlayers.size() == 1)
{
AnnounceEnd(teamsWithPlayers.get(0));
SetState(GameState.End);
return;
}
// Wither Dead check
for (GameTeam team : GetTeamList())
{
WitherBoss boss = _boss.getWitherBoss(team);
LivingEntity entity = boss.getEntity();
// Dead Wither
if (entity == null || !entity.isValid() || entity.isDead())
{
// Get the other team
for (GameTeam otherTeam : GetTeamList())
{
for (Player player : otherTeam.GetPlayers(true))
{
AddGems(player, 10, "Participation", false, false);
}
if (team.equals(otherTeam))
{
continue;
}
for (Player player : otherTeam.GetPlayers(true))
{
AddGems(player, 20, "Winning", false, false);
}
AnnounceEnd(otherTeam);
SetState(GameState.End);
}
}
}
}
@Override
public void RespawnPlayer(Player player)
{
super.RespawnPlayer(player);
player.setGameMode(GameMode.ADVENTURE);
}
@Override
public void disable()
{
super.disable();
_listeners.forEach(UtilServer::Unregister);
_listeners.clear();
_betaWhitelist.deregisterSelf();
}
@Override
public void SetKit(Player player, Kit kit, boolean announce)
{
super.SetKit(player, kit, announce);
if (kit instanceof HeroKit)
{
getMobaData(player).setKit((HeroKit) kit);
}
}
@Override
public DeathMessageType GetDeathMessageType()
{
return DeathMessageType.Detailed;
}
// Clear up memory
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
_playerData.removeIf(mobaPlayer -> mobaPlayer.getPlayer().equals(player));
}
// Clean up arrows
@EventHandler
public void projectileHit(ProjectileHitEvent event)
{
if (event.getEntity() instanceof Arrow)
{
event.getEntity().remove();
}
}
// Undisguise everyone upon game end
@EventHandler
public void end(GameStateChangeEvent event)
{
if (event.GetState() != GameState.End && event.GetState() != GameState.Dead)
{
return;
}
for (Player player : Bukkit.getOnlinePlayers())
{
DisguiseBase disguise = Manager.GetDisguise().getActiveDisguise(player);
if (disguise != null && disguise instanceof DisguisePlayer)
{
Manager.GetDisguise().undisguise(disguise);
}
}
}
public Map<String, Location> getLocationStartsWith(String s)
{
Map<String, Location> map = new HashMap<>();
for (String key : WorldData.GetAllCustomLocs().keySet())
{
if (key.startsWith(s))
{
map.put(key, WorldData.GetCustomLocs(key).get(0));
}
}
return map;
}
public GameTeam getTeam(String name)
{
for (GameTeam team : GetTeamList())
{
if (team.GetName().equalsIgnoreCase(name))
{
return team;
}
}
return null;
}
public HeroKit[] getKits()
{
return _kits;
}
public List<HeroKit> getKits(MobaRole role)
{
List<HeroKit> kits = new ArrayList<>();
for (HeroKit kit : _kits)
{
if (kit.getRole() == role && kit.isVisible())
{
kits.add(kit);
}
}
return kits;
}
public Set<MobaPlayer> getMobaData()
{
return _playerData;
}
public MobaPlayer getMobaData(Player player)
{
for (MobaPlayer mobaPlayer : _playerData)
{
if (mobaPlayer.getPlayer().equals(player))
{
return mobaPlayer;
}
}
return null;
}
public HeroKit getFirstKit(Player player)
{
MobaPlayer mobaPlayer = getMobaData(player);
if (mobaPlayer.getRole() == null)
{
MobaRole role = getRandomRole(player);
return getFirstKit(role);
}
else if (mobaPlayer.getKit() == null)
{
return getFirstKit(mobaPlayer.getRole());
}
return null;
}
private HeroKit getFirstKit(MobaRole role)
{
for (HeroKit kit : _kits)
{
if (kit.getRole() == role && kit.isVisible())
{
return kit;
}
}
return null;
}
private MobaRole getRandomRole(Player player)
{
List<MobaRole> roles = new ArrayList<>();
for (MobaPlayer mobaPlayer : getTeamData(GetTeam(player)))
{
MobaRole role = mobaPlayer.getRole();
if (role != null)
{
roles.add(role);
}
}
return UtilAlg.Random(Arrays.asList(MobaRole.values()), roles);
}
private List<MobaPlayer> getTeamData(GameTeam team)
{
List<MobaPlayer> players = new ArrayList<>();
for (MobaPlayer mobaPlayer : _playerData)
{
GameTeam otherTeam = GetTeam(mobaPlayer.getPlayer());
if (team.equals(otherTeam))
{
players.add(mobaPlayer);
}
}
return players;
}
public boolean isRoleFree(Player player, MobaRole role)
{
GameTeam team = GetTeam(player);
if (team == null)
{
return false;
}
for (MobaPlayer mobaPlayer : getTeamData(team))
{
if (mobaPlayer.getRole() == role)
{
return false;
}
}
return true;
}
public CustomScoreboardModule getScoreboardModule()
{
return getModule(CustomScoreboardModule.class);
}
public MobaShop getShop()
{
return _shop;
}
public GoldManager getGoldManager()
{
return _goldManager;
}
public TowerManager getTowerManager()
{
return _tower;
}
public CapturePointManager getCapturePointManager()
{
return _capturePoint;
}
public BossManager getBossManager()
{
return _boss;
}
public ArrowKBManager getArrowKbManager()
{
return _arrowKb;
}
public BuffManager getBuffManager()
{
return _buffs;
}
}

Some files were not shown because too many files have changed in this diff Show More