296 Commits
Author SHA1 Message Date
jomo 230e447ea5 use directory (untested!) 2014-08-07 03:00:44 +02:00
Louis Vogt 46d24a64c6 Initial commit (please split the commands into modules) 2014-08-07 02:39:05 +02:00
Louis Vogt ed26126de1 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-08-07 02:36:23 +02:00
jomo c87adff9ba use new thread for reports list 2014-08-07 02:30:44 +02:00
jomo ec192ad790 get rid of dico's stupid nonsense :3 2014-08-07 02:27:49 +02:00
jomo 7c2c87a05e get rid of offlineplayer in friends 2014-08-07 02:24:45 +02:00
jomo 939e744a33 get rid of OfflinePlayer in forcefield 2014-08-07 02:21:44 +02:00
jomo b7aed64fe5 remove WTF methods from player welcome 2014-08-07 02:19:53 +02:00
jomo 217f2cb579 fix %s 2014-08-07 02:10:36 +02:00
jomo b9f4d468ae clarifiy known_player a bit more 2014-08-07 01:50:26 +02:00
Louis Vogt fa6aaf0dff Modified known_player method 2014-08-07 01:46:53 +02:00
jomo c30578525f better /lol search 2014-08-07 01:39:12 +02:00
jomo bbbd180b98 revert to mob.chicken.plop, lavapop can be overheard easiliy 2014-08-07 01:26:28 +02:00
jomo 911d61b9e5 add note if no keywords 2014-08-07 01:25:20 +02:00
jomo 2dff50201a change highlight style. (underline hides parts of the next line) 2014-08-07 01:18:11 +02:00
jomo 2d5d6aace0 keyword must be IN the word, not exaclty the word 2014-08-07 01:17:26 +02:00
jomo 881c413642 don't be racist against players with uppercase characters in their name 2014-08-07 01:11:15 +02:00
jomo 24d341f833 delete mentions if empty 2014-08-07 01:06:19 +02:00
jomo 97b6c3a152 rewrite big parts of mentio 2014-08-07 00:59:13 +02:00
jomo 5cac70af31 FIX THIS BEFORE MERGING! 2014-07-31 00:07:15 +02:00
jomo db50be458f nicer string concatenating 2014-07-30 23:51:23 +02:00
jomo 08cae3213e remove try/except. fix code if it doesn't work ;) 2014-07-27 23:55:15 +02:00
jomo 180680422a catch all exceptions in pyeval 2014-07-27 23:29:55 +02:00
jomo 712cd135fc better name + docs for played_before (renamed to known_player) 2014-07-27 22:44:12 +02:00
jomo b18bdb69cb more documentation 2014-07-27 22:39:20 +02:00
jomo a9b9fc6ae5 rename log to info 2014-07-27 22:20:18 +02:00
jomo d4f618aa99 add warn() logging 2014-07-27 22:17:24 +02:00
jomo 3cfb585c8b readability 2014-07-27 21:52:55 +02:00
jomo 2a080b37a6 mentio readability, remove <> around mention highlight 2014-07-27 19:49:55 +02:00
jomo 54beea6ee5 readability 2014-07-27 19:43:06 +02:00
jomo aad63e5416 apply file read/save helpers 2014-07-27 19:42:33 +02:00
jomo 2e7e021001 add path to save/open json file 2014-07-27 06:04:31 +02:00
jomo a854fa2039 add default to open_json_file 2014-07-27 06:01:52 +02:00
jomo e277b923a7 better use of plugin_header in saylol 2014-07-27 05:41:25 +02:00
jomo e65122d4b3 add /lol search <text> 2014-07-27 05:28:31 +02:00
Louis Vogt fe2cafe5c9 Wrong receiver; new plop; no simplejson; still 1 bug 2014-07-26 14:19:31 +02:00
jomo e67fe48317 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-25 00:05:51 +02:00
jomo 7096d7036e link to latest python loader jar, remove jython download 2014-07-25 00:05:42 +02:00
Louis Vogt 7b1cd0799f Enabled custom mentions (not tested yet) 2014-07-24 15:20:23 +02:00
jomo e35b079263 allow to reset motd 2014-07-24 02:31:34 +02:00
jomo 993d1cf04c clean up friends.py 2014-07-24 02:12:54 +02:00
jomo 82c3015c04 readme stuff
- avoid long methods
- clarify errors
- better traceback example
2014-07-24 01:19:55 +02:00
Dico 0fd4894550 Minor change 2014-07-23 01:04:53 +02:00
Dico 627e02226d Removed useless lines 2014-07-23 00:56:31 +02:00
Dico 2b409b0ccc Didn't add module last time...? 2014-07-23 00:55:32 +02:00
Dico a962e0b6a8 Added friends module. Thanks piggly for testing! :D 2014-07-23 00:53:24 +02:00
jomo fa68622d2d remove test code 2014-07-23 00:00:18 +02:00
jomo 98b2f564bc trying stuff 2014-07-22 00:46:00 +02:00
jomo 85eff42481 use &-colors for motd on first load 2014-07-21 02:35:06 +02:00
jomo 22cc16cc48 remove test line 2014-07-21 02:34:36 +02:00
jomo 600e6c9c2f fix plugin_header 2014-07-21 02:31:46 +02:00
jomo ee80672d38 raise test error 2014-07-21 02:28:39 +02:00
jomo c973025a8e add /modules command
lists all modules.
green if loaded, red otherwise
2014-07-21 02:24:43 +02:00
jomo eb287681d1 fix problem with 'none' permission 2014-07-21 02:07:45 +02:00
jomo 38cf2eb153 nicer pyeval output 2014-07-21 02:06:15 +02:00
jomo 9dba5641e1 fix broken broadcast 2014-07-20 17:53:19 +02:00
jomo f48dcf11ef deploying details added to readme 2014-07-20 17:05:15 +02:00
jomo 3806af1f66 renamed fyle to f 2014-07-20 16:46:20 +02:00
jomo c527d21de5 fix horidicode 2014-07-20 16:37:41 +02:00
Dico a0f5b99745 README.md edited online with Bitbucket 2014-07-19 03:10:02 +00:00
Dico 5f6b2409aa Fixed shecode. I knowo that 'file' is the correct spelling, but that does weird stuff and turns blue so just leave it this works and sheeps code doesnt <3 2014-07-19 05:02:09 +02:00
Dico aa0357f0da Added toggle() to helpers.py. I haven't tested it thoroughly but it doesn't give errors on start. You can read the comment for more info :D 2014-07-19 04:53:51 +02:00
jomo 9624107acd fix dicallignment 2014-07-19 02:41:44 +02:00
jomo 6ea1ae8718 use name for CG logs 2014-07-19 02:37:57 +02:00
jomo 59219cb7a0 fix re-writing variable 2014-07-19 02:32:35 +02:00
jomo cbdab2504d fix dicode 2014-07-19 02:19:12 +02:00
jomo ccd0e3cd09 fix imports 2014-07-19 02:02:42 +02:00
Dico 16c95e4a12 Minor tweaks and fixes 2014-07-19 02:00:54 +02:00
Dico 0f5e5335b2 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-19 01:52:27 +02:00
Dico 2885e20669 Small fixes and tweaks 2014-07-19 01:51:29 +02:00
jomo 45376bc38f remove forcefield for merge with master 2014-07-19 01:50:35 +02:00
Dico a8a37f0553 Stuff added to helpers.py, forcefield updated to be a lot more efficient (simple change) 2014-07-19 01:39:08 +02:00
Dico c01caf04a9 minor changes. @Sheep: Take a look at the changes I made to helpers module and tell me if I'm stupid. 2014-07-18 03:45:28 +02:00
Dico c5a6d0b52b Git messed around with my files, I updated it to use the uid() function in helpers.py now. 2014-07-18 02:50:14 +02:00
Dico 38ae7372ca wtf git adding random stuff to my files 2014-07-18 02:36:52 +02:00
Dico a38eb33760 Happy with this version/build. @Sheep: Don't fix my 'dicode'! 2014-07-18 02:27:24 +02:00
jomo 44d0541b29 use uid(player) helper method 2014-07-17 22:24:45 +02:00
jomo 9dd5555fb3 using is_creative helper 2014-07-17 22:13:49 +02:00
jomo 69f6423028 make dicode DRY and more readable 2014-07-17 21:36:05 +02:00
Dico a53957e888 Rewrote velocity calculation. 2014-07-17 17:47:49 +02:00
Dico c00c36076a Minor fix 2014-07-17 16:06:11 +02:00
Dico a54263a59d Converted reports module to UUID and minor changes to forcefield module 2014-07-17 15:26:48 +02:00
Dico b1f00d3fe4 removing feature which doesnt work and is stupid 2014-07-17 05:40:54 +02:00
Dico db6faa69ae Cool stuff 2014-07-17 05:29:55 +02:00
Dico 546ce7cfb2 Another minor change 2014-07-17 05:10:24 +02:00
Dico c4a8fc9358 Minor change 2014-07-17 04:54:44 +02:00
Dico b7fef7607b No saving to files yet, but it definitely works well now. 2014-07-17 04:49:31 +02:00
Dico fb1655e01b Updates! YAY! 2014-07-17 03:48:14 +02:00
Dico 432d249878 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-17 01:17:28 +02:00
jomo 3691fa6503 show return type in pyeval 2014-07-17 01:16:37 +02:00
Dico e4dbf1c458 Working version 2014-07-17 01:13:22 +02:00
jomo f4381ae7c2 undo dicode 2014-07-17 00:52:22 +02:00
Dico e2ba62fd9d Fixing bugs & Cleaning up code. Seems to work well now! 2014-07-17 00:48:41 +02:00
jomo 59e16e24a6 debugging 2014-07-16 02:15:23 +02:00
jomo 8f0d9611b0 debugging 2014-07-16 02:11:52 +02:00
jomo 0bf4cddb95 use better names, fix bugs 2014-07-16 02:04:02 +02:00
jomo e65b8e25fb add readability spacing 2014-07-16 01:08:04 +02:00
jomo 4d04d8df5b add readability to coding guidelines 2014-07-16 00:59:02 +02:00
jomo 1a6e60fec4 more code cleanup 2014-07-16 00:49:55 +02:00
jomo 195cf2c7ec added Pro Tip (tm) 2014-07-16 00:39:25 +02:00
jomo 433b2d3bbb clarified camelCase usage 2014-07-16 00:38:15 +02:00
jomo 65c3bb1371 corrected s/idToPlayer/java_uuid/ 2014-07-16 00:34:49 +02:00
jomo 0e65631ece removed camelcase, added more coding style to readme 2014-07-16 00:33:43 +02:00
Dico 8637976c76 Sorry for spam 2014-07-15 19:36:50 +02:00
Dico cde51fd6f6 Fixing movement bugs 2014-07-15 19:16:30 +02:00
Dico cb8e92a168 Think I finally fixed ALL forcefield bugs, command-side-wise 2014-07-15 18:49:36 +02:00
Dico 35e7bf098f Fixing moar bugs! 2014-07-15 14:19:45 +02:00
Dico 9ae650549c Fixing bugs... 2014-07-15 14:07:48 +02:00
Louis Vogt 70da17408f Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-14 16:23:33 +02:00
Louis Vogt cc17a53f0e Added WIP custom words 2014-07-14 16:22:49 +02:00
Dico 7d0d0fd3c7 Unfixing fix 2014-07-14 13:38:26 +02:00
Dico 4b19546c13 Fixing bugs 2014-07-14 13:32:37 +02:00
Dico fa0823b15b Added forcefield whitelist and hopefully fixed some bugs 2014-07-14 13:08:15 +02:00
jomo 4de83c5114 check for cancelled event 2014-07-14 06:04:06 +02:00
jomo a03bb67d85 check if player can build 2014-07-14 06:01:21 +02:00
jomo fb5a61b8d4 using floats for timeout 2014-07-14 05:57:27 +02:00
jomo ab24808f0d better message formatting 2014-07-14 05:42:44 +02:00
jomo c6dca4ac94 need more caffeine 2014-07-14 05:42:23 +02:00
jomo a272a615e4 fix time check 2014-07-14 05:33:46 +02:00
jomo 5cee964b9c fix plugHeader, store last time 2014-07-14 05:32:14 +02:00
jomo 665fbcb430 I should stop using copy pasta 2014-07-14 05:27:59 +02:00
jomo 626da9fb5c range starts at 0 2014-07-14 05:25:57 +02:00
jomo 35e59583bc cannot join string with ints 2014-07-14 05:24:08 +02:00
jomo fac11c147d don't accept 0 args, remove try 2014-07-14 05:20:30 +02:00
jomo 219bc0751b add damnspam to load_modules 2014-07-14 05:17:29 +02:00
jomo b082d6fdae Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-14 05:16:59 +02:00
jomo 0262d428d0 damnspam 2014-07-14 05:16:48 +02:00
Dico b75f4505d1 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-14 02:42:45 +02:00
Dico 94b849b81c added forcefield module, will make whitelist option later 2014-07-14 02:40:00 +02:00
jomo 69ac22c69a clarify how to use CG 2014-07-14 01:26:42 +02:00
jomo 0d9613911c logging groupchat messages 2014-07-14 01:25:12 +02:00
jomo 4c0a482a3c add noperm; return true 2014-07-14 01:20:42 +02:00
jomo 69b21c6acf fix basecolor in abot 2014-07-14 01:20:11 +02:00
jomo e36dbaeb44 add mising import 2014-07-14 01:17:51 +02:00
jomo 086a1fe064 creating shared dict 2014-07-14 01:16:40 +02:00
jomo ba10e82171 getting the right name in pluginversions 2014-07-14 01:00:30 +02:00
jomo c6bfe7c3d1 getting the right name in pluginversions 2014-07-14 01:00:06 +02:00
jomo 5838739985 can't call function before definition 2014-07-14 00:56:46 +02:00
jomo 7a53704e60 use json config for abot 2014-07-14 00:54:25 +02:00
jomo 1f5ee6b348 using jython 2.7b2 2014-07-13 17:10:14 +02:00
jomo e9f1142cea typo fix 2014-07-13 17:03:11 +02:00
jomo 837b68e9f9 fix merge conflicts 2014-07-13 16:35:21 +02:00
jomo 0151ca55ed use uuid in CG 2014-07-13 16:34:31 +02:00
Louis Vogt e5b6f27b61 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-12 11:06:13 +02:00
Louis Vogt 4b6bd6eaa2 Added DamnSpam to descriptions 2014-07-12 11:05:08 +02:00
jomo 5f2cf0b19e fix double quites 2014-07-12 03:10:42 +02:00
jomo 6771be27de Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-12 03:08:10 +02:00
jomo cb7c8550fd show online users by UUID; add quotes info to readme 2014-07-12 03:08:01 +02:00
Louis Vogt ba7f03f5e1 Added WIP DamnSpam module 2014-07-12 01:47:32 +02:00
Louis Vogt cd0358de2b Changed single quotes to double quotes 2014-07-12 01:17:13 +02:00
Louis Vogt 80dcbb3d13 Uses UUID now + cg_key is now : 2014-07-11 23:50:27 +02:00
jomo 90b2968df3 more abot fixes 2014-07-11 00:26:49 +02:00
jomo cba20fa67a more abot fixes 2014-07-10 23:45:32 +02:00
jomo be988fb9e5 match e.g. who can clear plot 2014-07-10 23:36:36 +02:00
jomo 71f5f46ff7 remove empty matchgroup; first match has to be a word 2014-07-10 23:35:03 +02:00
jomo bd94ee9076 fix false positive for e.g. MODel, MODern 2014-07-10 23:32:23 +02:00
jomo bb2bb0ecc8 fix false positive for e.g. MODel, MODern 2014-07-10 23:30:35 +02:00
jomo b9e73b58d7 skip abot for players with 'utils.ignore_abot' permission 2014-07-10 23:08:23 +02:00
jomo 3f212dc451 fix literal '.' in regex, fixes 2014-07-10 23:06:45 +02:00
jomo 33169883fb more noob matching 2014-07-10 22:58:47 +02:00
jomo d89f649ca0 needs trailing space 2014-07-10 01:22:53 +02:00
jomo f526f521b5 fix typo, nicer output 2014-07-10 01:21:14 +02:00
jomo ea7284f2c8 do not require extra words 2014-07-10 01:11:25 +02:00
jomo b284f6940f fucking comma 2014-07-10 01:03:39 +02:00
jomo 8bac5b5331 fix braces 2014-07-10 00:55:04 +02:00
jomo 5846d0f765 more questions 2014-07-10 00:52:32 +02:00
jomo a0f02fb846 add abot (AnswerBot) to get rid of stupid FAQ asking 2014-07-10 00:37:42 +02:00
jomo a87b9eb9d1 fix double plugin header 2014-07-09 00:24:55 +02:00
jomo 2d02165d06 add /echo 2014-07-09 00:18:26 +02:00
jomo 888136e30a make AC prefix red 2014-07-08 20:30:11 +02:00
jomo b43d99b8bf removed unused commands from welcome message 2014-07-08 19:55:54 +02:00
jomo 81147baa11 fix out of range /lol id 2014-07-08 02:17:37 +02:00
jomo b2d69ff507 use cycle plugin in creative mode only 2014-07-06 20:49:11 +02:00
jomo 616ddd4cfc remove text-only commands, use commands.yml aliases 2014-07-05 21:28:26 +02:00
jomo fd212674c1 add 0.4s delay to shearing 2014-07-05 21:12:27 +02:00
jomo 1c2c3782c7 175:6 is no longer breaking clients 2014-07-05 21:05:47 +02:00
jomo 6ccbf25d87 tell people to use website 2014-07-05 21:05:18 +02:00
jomo a1df5c73e8 avoid using deleting e.g. reports[-1] 2014-07-05 18:58:22 +02:00
jomo e32edd981e fix broken report deletion 2014-07-05 18:54:52 +02:00
jomo dd2e16ef57 allow newlines 2014-07-04 02:04:59 +02:00
jomo 217dc64c87 fix broadcast 2014-07-04 02:00:04 +02:00
jomo 0a04de8c0e fix plugin title 2014-07-04 01:54:23 +02:00
jomo f9744d787c fix plugin title 2014-07-04 01:53:33 +02:00
jomo 340e09777e add motd.py 2014-07-04 01:50:36 +02:00
jomo 39a9644a1f fix deleteing non-existing report 2014-07-02 01:13:12 +02:00
jomo 81deba5af2 fix shearsheep 2014-07-02 00:27:50 +02:00
jomo 93f87a167d fix typi 2014-06-29 18:28:13 +02:00
jomo cc547dc543 don't cycle when sneaking 2014-06-29 18:26:02 +02:00
jomo 4dbabb5ed2 use strings for UUID 2014-06-29 16:25:17 +02:00
jomo 6cb477e3df add newline to plugin headers 2014-06-29 16:22:28 +02:00
jomo 7e86a2b6a9 save file on list change, fix up/down naming, remove logging 2014-06-29 16:21:59 +02:00
jomo 4909e1a452 save file 2014-06-29 16:15:42 +02:00
jomo f116d937ec fix indentation 2014-06-29 15:38:51 +02:00
jomo 5b7566ea67 better loggin 2014-06-29 15:37:45 +02:00
jomo bbc12659c2 shift items, then check for empty line 2014-06-29 15:33:27 +02:00
jomo 7a0d0fee72 shift items, then check for empty line 2014-06-29 15:21:16 +02:00
jomo ead78abd1c move cycle plugin to new module; add features 2014-06-29 15:18:25 +02:00
jomo 5012696c56 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-06-29 09:19:43 +02:00
jomo 45f105ec61 use list(x) instead of x.tolist() 2014-06-29 09:19:33 +02:00
shillingp f2f6b49a7b Complete inventory cycle 2014-06-27 15:16:03 +00:00
jomo 4313bb90fd make gettoken more user-friendly 2014-06-25 02:40:49 +02:00
jomo 280525170c Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-06-25 02:36:07 +02:00
jomo 0be9493448 rename tokengen/gettoken 2014-06-25 02:35:47 +02:00
shillingp 1dee504cfd misc.py edited online with Bitbucket 2014-06-23 23:09:55 +00:00
shillingp 1e0b45fb17 getInventory not getContents 2014-06-23 23:07:25 +00:00
shillingp bec8a28302 changed inventory event to player event 2014-06-23 22:59:59 +00:00
shillingp af302f2ca9 Added inventory cycle function 2014-06-23 22:52:04 +00:00
jomo 32eae1b248 fix comments 2014-06-23 03:16:09 +02:00
jomo 500b62affd Merge branch 'dev' 2014-06-23 01:18:28 +02:00
jomo 7711b62b9e adjust rules 2014-06-23 01:18:15 +02:00
jomo fb2cd7d3b7 fix rule alignment; change color 2014-06-23 01:02:09 +02:00
jomo 90e6fe9280 fixed wrong prefix in /cgt 2014-06-23 00:34:00 +02:00
jomo 56e50c81f9 add mentio.py again, now working 2014-06-22 02:15:01 +02:00
jomo 57c721cbc6 Merge branch 'dev' 2014-06-22 02:12:05 +02:00
jomo 0793413501 awesome new feature 2014-06-22 02:11:43 +02:00
jomo 9dc890f2fa fix deprecated event 2014-06-21 14:39:43 +02:00
jomo 8e3585934b fixed wrong event priority names 2014-06-21 14:34:00 +02:00
jomo 65c4affba8 y u no work 2014-06-21 14:32:07 +02:00
jomo 6f0514709d derp, need to use lower event so ac cancels before mentio 2014-06-21 14:26:24 +02:00
jomo f0fb488eb8 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-06-21 14:07:15 +02:00
jomo 4ad50fa688 use asyncplayerchatevent for adminchat, listen after mentio 2014-06-21 14:07:05 +02:00
jomo 277a571e4a fixed spigot link 2014-06-21 11:06:27 +00:00
jomo aa8ffd95b1 using list(x) instead of x.tolist() 2014-06-21 12:50:03 +02:00
jomo 5431cd2b90 only using recipient list when iterating 2014-06-21 12:47:25 +02:00
jomo 086902a202 rename tokengen to gettoken, add warning 2014-06-21 12:43:16 +02:00
jomo 927ea4d57a lots of stuff for readme 2014-06-21 12:38:44 +02:00
jomo b1be92f1a9 catch java exceptions, too 2014-06-21 11:09:10 +02:00
jomo 2b6dd6555e ignore everything in files/ 2014-06-21 11:08:18 +02:00
jomo 0494b82bf0 catch java exceptions, too 2014-06-21 11:05:59 +02:00
Louis Vogt 1e399a002a Converted set into list 2014-06-21 10:01:35 +02:00
jomo 2e31e3a463 remove mention due to error spam 2014-06-21 02:29:04 +02:00
jomo 2b89ec586c copying recipients before iterating 2014-06-21 01:18:00 +02:00
jomo 6963b02a03 catch everything 2014-06-21 01:12:27 +02:00
jomo e483f12630 quick fix 2014-06-21 01:00:21 +02:00
jomo c150fae053 fix colors, highlight word, create sound 2014-06-21 00:52:16 +02:00
jomo 3e27b2691b better way to debug plugins 2014-06-20 22:24:20 +02:00
jomo 0b2fec7271 add (unused) code to create awesome screenshots :D 2014-06-20 22:23:09 +02:00
Louis Vogt 72219d9e27 Fixed indention. Finally. 2014-06-20 22:16:17 +02:00
Louis Vogt 51725b9add Fixed intentation+spelling mistake 2014-06-20 22:13:09 +02:00
Louis Vogt 557142e82b Added mention module 2014-06-20 22:04:39 +02:00
Louis Vogt 3095761138 Added mention module 2014-06-20 21:56:30 +02:00
jomo 4e5ef743b6 delete files/ 2014-06-17 00:20:10 +02:00
jomo 366ac59901 remove tilehelper for master 2014-06-17 00:11:49 +02:00
shillingp 8d0a66d492 spelling mistakes 2014-06-16 22:09:20 +00:00
shillingp 18aee5a48e Messages altered and colored 2014-06-16 22:03:44 +00:00
shillingp 473c7c9ffd Fixed fail if statement 2014-06-16 21:53:12 +00:00
shillingp cceb7e7b53 spawn to teleport command, implemented head position 2014-06-16 21:41:06 +00:00
shillingp 7508938dbe Import material removed, material as string 2014-06-16 21:24:06 +00:00
shillingp c2275ee0bc Import materials for Material.PORTAL 2014-06-16 21:21:22 +00:00
jomo 4e9241c97e Merged in shillingp/portal-safety-1402935495123 (pull request #1)
misc.py added login portal safety
2014-06-16 23:11:58 +02:00
shillingp 684c0c50e3 misc.py added login portal safety 2014-06-16 16:19:32 +00:00
jomo d6635c8951 log errors 2014-06-11 23:10:39 +02:00
jomo c8d61d0c18 use simplejson 2014-06-10 06:32:28 +02:00
jomo b764aa6bf4 load tilehelpers from file 2014-06-10 06:25:25 +02:00
jomo 3936f14861 sleep 2 ticks so changes can be applied 2014-06-10 06:06:40 +02:00
jomo 768391fb60 handle right click 2014-06-10 06:01:59 +02:00
jomo 2d608a8cee bugfix 2014-06-10 05:43:36 +02:00
jomo ec16b0045f fix block data; use Interact instead of DamageEvent 2014-06-10 05:31:39 +02:00
jomo 6459884627 add BlockDamageEvent 2014-06-10 05:17:44 +02:00
jomo 9302451854 use data from blockstate 2014-06-10 05:15:10 +02:00
jomo 0a16b25ef5 add data to blockPlaceEvent 2014-06-10 05:12:18 +02:00
jomo 1c6931c027 remove debug output 2014-06-10 04:57:11 +02:00
jomo d7c80d5034 bugfixes 2014-06-10 04:53:36 +02:00
jomo c9bd89a3bb AAAARGH 2014-06-10 04:50:55 +02:00
jomo 68df60865c cannot believe this... BrakeEvent >_< 2014-06-10 04:47:59 +02:00
jomo acfd84906f added BlockBrakeEvent 2014-06-10 04:45:01 +02:00
jomo 68d627b6fc oops 2014-06-10 04:23:13 +02:00
jomo f92baebf68 trying to use new block AND new block's state 2014-06-10 04:19:41 +02:00
jomo 1ab86ffc6f debugging 2014-06-10 04:17:37 +02:00
jomo 4916bd0382 debugging 2014-06-10 04:13:04 +02:00
jomo 843c34051f debugging 2014-06-10 04:01:46 +02:00
jomo fc0030b326 debugging 2014-06-10 03:58:40 +02:00
jomo 1e80e50b1f oops, need to use newblock, not newagainst 2014-06-10 03:46:59 +02:00
jomo e0393b4d63 debug 2014-06-10 03:44:02 +02:00
jomo 84404fbffd using block from blockstate 2014-06-10 03:15:23 +02:00
jomo f32f44d7d1 changing blockstate 2014-06-10 03:10:10 +02:00
jomo 0db39e5ca1 set block if event was not cancelled 2014-06-10 02:39:50 +02:00
jomo 3bf227ea1c move /pyeval back to main.py, so modules can be accessed 2014-06-10 01:36:18 +02:00
jomo cb716abd6b HUGE code cleanup 2014-06-10 01:31:03 +02:00
jomo 3dd467afec fix endless loop? 2014-06-10 00:32:48 +02:00
jomo cec624a833 fix endless loop 2014-06-10 00:30:54 +02:00
jomo 535dbcc94b test 2014-06-10 00:22:54 +02:00
jomo e574e8e914 firing event in defined directions 2014-06-10 00:20:02 +02:00
jomo d582e8a457 add missing import option 2014-06-09 23:54:48 +02:00
jomo e853681df6 better loading / importing of modules 2014-06-09 23:52:11 +02:00
jomo bc301a3cb2 remove executable bit 2014-06-07 20:15:46 +02:00
jomo 095df21073 remove executable bit 2014-06-07 20:13:10 +02:00
jomo b3c3886ffe started tilehelper plugin 2014-06-07 01:27:06 +02:00
jomo aef7d5df3b fix path 2014-05-17 01:17:05 +02:00
jomo 4754083725 change mode 775 2014-05-17 01:09:35 +02:00
jomo 33c98181f8 add default files to prevent errors on first start 2014-05-17 00:46:22 +02:00
jomo e645949bab remove ingame dependent files 2014-05-17 00:45:00 +02:00
jomo 49edec4a9f yea, i actually forgot this plugin itself... >_< 2014-05-17 00:35:32 +02:00
jomo ea277cb3ab add README 2014-05-17 00:22:35 +02:00
jomo 0227c2071e rename mysql-connector 2014-05-17 00:14:40 +02:00
jomo b7de342537 first commit via git 2014-05-16 23:04:40 +02:00
55 changed files with 1630 additions and 6370 deletions
-4
View File
@@ -1,10 +1,6 @@
*.pyc *.pyc
*.class *.class
*sublime* *sublime*
*.bat*
secrets.py
excluded.txt
.idea
# these are player/ingame specific # these are player/ingame specific
files/ files/
-1
View File
@@ -1 +0,0 @@
If you want to contribute, please [read through the pages on the wiki](https://github.com/RedstonerServer/redstoner-utils/wiki).
-21
View File
@@ -1,21 +0,0 @@
# The MIT License (MIT)
Copyright (c) Redstoner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE
+240 -3
View File
@@ -2,8 +2,245 @@
Redstoner's custom plugins, written in python. Redstoner's custom plugins, written in python.
------
## Contributing # Installation / Set-up
If you want to contribute, please [read through the pages on the wiki](https://github.com/RedstonerServer/redstoner-utils/wiki). 1-line-install-script for bash:
`wget -O install.sh "http://pastie.org/pastes/9310905/download?key = 6byp4mrqmiui8yqeo3s6yw"; md5sum --check <<<"3499671c0832e561bc9c7d476d2167cb install.sh" && sh install.sh`
Detailed description:
0. Create a new directory called 'redstoner'
0. Download [the latest spigot](http://ci.md-5.net/job/Spigot/lastStableBuild/artifact/Spigot-Server/target/spigot.jar)
0. Run it once inside redstoner, then shut it down again
0. Create a new directory (inside redstoner) called 'lib'
0. Download [mysql-connector](https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.30.zip), extract 'mysql-connector-java-X.X.XX-bin.jar
' and save it as 'mysql-connector.jar' inside lib
0. Download [PyPluginLoader](http://bamboo.gserv.me/browse/PLUG-PYPL/latestSuccessful/artifact/JOB1/Version-agnostic-jar/PyPluginLoader.jar) (we're using [this fork](https://github.com/gdude2002/Python-Plugin-Loader)) into the plugins directory
0. inside plugins, clone this directory into 'redstoner-utils**.py.dir**':
`git clone git@bitbucket.org:redstonesheep/redstoner-utils.git redstoner-utils.py.dir`
0. Download [PEX](http://dev.bukkit.org/media/files/789/291/PermissionsEx.jar) into plugins
0. **if you want** to develop mysql things, set up a local MySQL server
# branches
* **dev**
Always use this branch to change code, please test before pushing. (If something goes wrong here, that's okay)
* **master**
Never commit into this branch directly! Only merge stable versions of *dev*:
```bash
git checkout master
git merge dev
```
# Deploying on the server
**Never** edit the files directly on the server!
The dev server uses the *dev* branch, the live server uses *master*.
**Do not use `git pull` on the server!** *(All files must be pulled/owned by the 'redstoner' user.)*
### Deploying on test server
* Push all changes
* Run `<server-dir>/git_pull_utils.sh`.
* Restart (You can try reloading here, but expect the unexpected)
### Deploying on production server
* Test all code carefully on the test server
***on your machine:***
* `git checkout master`
* `git pull`
* `git merge dev`
* `git push -u origin master`
* `git checkout dev`
***on the server:***
* `rs update_utils`
* Restart
# Modules / Files
If you add a new file, please update this list!
If you want the server to load a file (*module*) on startup, add it to the `modules` list in `main.py`.
* `files/`
> All config / storage files go here
* `plugin.yml`
> The plugin.yml file required for bukkut plugins
* `main.py`
> The only file loaded by PyPluginLoader, loads all other modules
> Contains a few methods that **need to be cleaned up**
* `helpers.py`
> Library that adds a bunch of re-usable methods which are used in nearly all other modules
* `adminchat.py`
> Adds chat for staff using `/ac <text` or `,<text>`
* `chatgroups.py`
> Adds group-chat with `/chatgroup` and `/cgt` to toggle normal chat into group mode
* `lagchunks.py`
> Plugin to locate laggy chunks. `/lc <n>` lists chunks with more than `n` entities
* `mysqlhack.py`
> A library that makes use of the so called ClassPathHack for jython to allow proper loading of `mysql-connector.jar` at runtime. import only, no methods.
* `plotter.py`
> Start of a custom plot-plugin like PlotMe, on hold because the PlotMe developer continued to develop PlotMe
* `reports.py`
> The `/report <text>` and `/rp` plugin
* `saylol.py`
> Remake of sheep's old SayLol plugin, originally written as a standalone plugin in Java
* `skullclick.py`
> Shows the owner of a skull when right-clicked
* `webtoken.py`
> Adds `/token`, reads and writes from the database to generate *pronouncable* (and thus memorable) registration-tokens for the website
* `spawnplayer.py`
> Code that was used once to create [this](http://www.reddit.com/r/Minecraft/comments/28le52/screenshot_of_all_players_that_joined_my_server/) awesome [screenshot](http://i.imgur.com/v4wg5kl.png)
* `tilehelper.py`
> A plugin that automatically tiles (stacks) blocks inside a selected region in configurable directions.
* `mentio.py`
> Adds `/listen`, highlights chat and plays a sound when your name was mentioned
* `cycler.py`
> Adds `/cycler`, swaps the hotbar with inventory when player changes slot from right->left or left->right
* `motd.py`
> Adds `/getmotd` & `/setmotd` to update the motd on the fly (no reboot).
* `abot.py`
> AnswerBot. Hides stupid questions from chat and tells the sender about `/faq` or the like
* `damnspam.py`
> Adds `/damnspam`, creates timeout for buttons/levers to mitigate button spam.
* `forcefield.py`
> Adds '/forcefield', creates forcefield for players who want it.
# Code styleguide & tips
## Indentation
Never use tabs!
Use 2 spaces to indent.
## Quotes
Always use double-quotes!
Only use single-quotes when the string contains double-quotes that would need to be escaped.
## Capitalization
Do not use camelCase for variable or function names! Use under_score naming.
camelCase is okay when used like `import foo.bar.camelCase as camelCase`.
## Aligning variable assignments
In case you have multiple variable assignments, align the equals sign:
```Python
# bad
foo = 1
foobar = 2
a = 3
# good
foo = 1
foobar = 2
a = 3
```
Pro Tip: Use the AlignTab plugin for Sublime Text!
## Horizontal spacing
Use at least one space left and one space right to equals signs, and one space right to colons.
## Vertical spacing
Leave two empty lines before function definitions. In case you need to use `@hook.something`, add the two lines before that, directly followed by the definition.
## Meaningful names
Give function and variable names meaningful names. If you want to shorten long names, that's fine, but leave a comment on assigment with the actual meaning.
## Readability
Don't create long lines with lots of function calls. Split into multiple lines instead.
Also avoid methods with lots of lines. Split into multiple methods instead.
```Python
# bad
foo = int(player_data[str(server.getPlayer(args[4]).getUniqueId())]["details"].["last_login"].strftime("%s"))
# good
player = server.getPlayer(args[4])
player_id = uid(player)
logintime = player_data[played_id]["last_login"]
epoch_time = int(logintime.strftime("%s"))
```
## Comments
Comments are good!
Please comment everything that's non-obious or makes it easier to understand
## Debugging
Debugging can be a bit special with jython/PyPluginLoader.
When something goes wrong, you probably see a weird traceback that's not telling you shit.
...unless you take a closer look.
You will not see a direct traceback of the python methods.
Instead, you'll probably see a bunch of java, bukkit and python things, because it tries to translate python into java, line per line.
Take a closer look at the method names, they might tell you what it's trying to do and where it's coming from.
Watch out for something like `org.python.pycode._pyx5.horribleCode$23(/path/to/badcode.py:214) ~[?:?]`
0. In this case, `_pyx5` is our module.
0. `horribleCode` is the method that was called
0. `/path/to/badcode.py` is the actual file of our module
0. `:214` is the line in which the error occured.
Please note that the line may not be accurate. You'll often get the start of a loop, or the end of a method - when the actual error was somewhere in there.
In many cases, this is enough to find your bug. If you still cannot find it,try to catch exceptions in your code, as follows:
## Catching exceptions
If you want to catch all exceptions (e.g. for debugging), do not `catch Exception`.
Since we're using jython, this will not catch Java exceptions.
This will give you some more deatails:
```python
from traceback import format_exc as trace
try:
#code
except: # everything
print(trace())
```
+41 -50
View File
@@ -5,68 +5,59 @@ answers = []
def load_answers(): def load_answers():
global answers global answers
answers = open_json_file("abot", []) answers = open_json_file("abot", [])
# compile answers # compile answers
for answer in answers: for answer in answers:
answer["regex"] = [reg_compile(reg.lower()) for reg in answer["regex"]] answer["regex"] = [reg_compile(reg.lower()) for reg in answer["regex"]]
def list_answers(sender): def list_answers(sender):
for answer in answers: for answer in answers:
msg(sender, "&e{") msg(sender, "&e{")
msg(sender, " &eregex:") msg(sender, " &eregex:")
for regex in answer["regex"]: for regex in answer["regex"]:
msg(sender, " " + regex.pattern, basecolor="a", usecolor = False) msg(sender, " " + regex.pattern, basecolor="a", usecolor = False)
msg(sender, " &epermission:") msg(sender, " &epermission:")
msg(sender, " " + str(answer["hide-perm"]), basecolor="a", usecolor = False) msg(sender, " " + str(answer["hide-perm"]), basecolor="a", usecolor = False)
msg(sender, " &emessage:") msg(sender, " &emessage:")
msg(sender, " " + "\n ".join(answer["message"].split("\n"))) msg(sender, " " + "\n ".join(answer["message"].split("\n")))
msg(sender, "&e}") msg(sender, "&e}")
@hook.command("abot") @hook.command("abot")
def on_abot_command(sender, command, label, args): def on_abot_command(sender, args):
plugin_header(sender, "AnswerBot") plugin_header(sender, "AnswerBot")
if sender.hasPermission("utils.abot.admin"): if sender.hasPermission("utils.abot.admin"):
if not args: if not args:
msg(sender, "&2/abot list &eList all answers and their regex") msg(sender, "&2/abot list &eList all answers and their regex")
msg(sender, "&2/abot reload &eReload the config file") msg(sender, "&2/abot reload &eReload the config file")
elif args[0] == "list": elif args[0] == "list":
list_answers(sender) list_answers(sender)
elif args[0] == "reload": elif args[0] == "reload":
load_answers() load_answers()
msg(sender, "&2Reloaded!") msg(sender, "&2Reloaded!")
else:
msg(sender)
else: else:
noperm(sender) msg(sender)
return True else:
noperm(sender)
return True
def check_msg(event, message):
sender = event.getPlayer()
for answer in answers:
for regex in answer["regex"]:
if regex.search(message):
if not answer["hide-perm"] or not sender.hasPermission(answer["hide-perm"]):
plugin_header(sender, "AnswerBot")
msg(sender, answer["message"] + "\n ")
event.setCancelled(True)
info("(hidden) %s: '%s'" % (sender.getName(), message))
break
@hook.event("player.AsyncPlayerChatEvent", "low") @hook.event("player.AsyncPlayerChatEvent", "low")
def on_chat(event): def on_chat(event):
check_msg(event, event.getMessage().lower()) sender = event.getPlayer()
message = event.getMessage().lower()
for answer in answers:
for regex in answer["regex"]:
if regex.search(message):
if not answer["hide-perm"] or not sender.hasPermission(answer["hide-perm"]):
plugin_header(sender, "AnswerBot")
msg(sender, answer["message"] + "\n ")
event.setCancelled(True)
info("(hidden) %s: '%s'" % (sender.getName(), message))
break
@hook.event("player.PlayerCommandPreprocessEvent", "low")
def on_any_cmd(event):
words = event.getMessage().lower().split(" ")
cmd = words[0][1:]
if cmd in ["msg", "m", "t", "pm", "mail", "r", "reply"]:
check_msg(event, " ".join(words[1:]))
load_answers() load_answers()
+33 -64
View File
@@ -1,86 +1,55 @@
#pylint: disable = F0401 #pylint: disable = F0401
from helpers import * from helpers import *
from basecommands import simplecommand
ac_permission = "utils.ac" ac_permission = "utils.ac"
ac_key = ","
ac_defaultkey = ","
ac_keys = open_json_file("adminchat_keys", {})
ac_toggle_list = [] ac_toggle_list = []
ac_prefix = "&8[&cAC&8]" ac_prefix = "&8[&cAC&8]"
def adminchat(sender, msg): def adminchat(sender, msg):
name = "&7{unknown}" name = "&7{unknown}"
try: try:
name = sender.getDisplayName() name = sender.getDisplayName()
except AttributeError: except AttributeError:
name = sender.getName() name = sender.getName()
broadcast(ac_permission, "%s &9%s&8: &b%s" % (ac_prefix, name, msg)) broadcast(ac_permission, "%s &9%s&8: &b%s" % (ac_prefix, name, msg))
# Needs something here like fine(message) to show up in the logs when you use ackey, but fine doesnt work for some reason. It did on the server with /pyeval (not show up on console, but show up in logs nevertheless)
# ac toggle # ac toggle
@hook.command("act") @hook.command("act")
def on_act_command(sender, args): def on_act_command(sender, args):
if sender.hasPermission(ac_permission): if sender.hasPermission(ac_permission):
p = sender.getName() p = sender.getName()
if p in ac_toggle_list: if p in ac_toggle_list:
ac_toggle_list.remove(p) ac_toggle_list.remove(p)
msg(sender, "%s &aAC toggle: off" % ac_prefix) msg(sender, "%s &aAC toggle: off" % ac_prefix)
else:
ac_toggle_list.append(p)
msg(sender, "%s &aAC toggle: on" % ac_prefix)
else: else:
noperm(sender) ac_toggle_list.append(p)
return True msg(sender, "%s &aAC toggle: on" % ac_prefix)
else:
noperm(sender)
return True
@hook.command("ac") @hook.command("ac")
def on_ac_command(sender, args): def on_ac_command(sender, args):
if sender.hasPermission(ac_permission): if sender.hasPermission(ac_permission):
if not checkargs(sender, args, 1, -1): if not checkargs(sender, args, 1, -1):
return True return True
adminchat(sender, " ".join(args)) adminchat(sender, " ".join(args))
else: else:
noperm(sender) noperm(sender)
return True return True
def get_key(uuid):
key = ac_keys.get(uuid)
return key if key != None else ac_defaultkey
@simplecommand("adminchatkey",
aliases = ["ackey"],
senderLimit = 0,
helpNoargs = True,
helpSubcmd = True,
description = "Sets a key character for adminchat",
usage = "<key>")
def adminchatkey_command(sender, command, label, args):
key = " ".join(args)
uuid = uid(sender)
if key.lower() == "default" or key == ac_defaultkey:
del ac_keys[uuid]
save_keys()
return "&aYour adminchat key was set to the default character: '&c%s&a'" % ac_defaultkey
ac_keys[uid(sender)] = key
save_keys()
return "&aYour adminchat key was set to: '&c%s&a'" % key
def save_keys():
save_json_file("adminchat_keys", ac_keys)
@hook.event("player.AsyncPlayerChatEvent", "low") @hook.event("player.AsyncPlayerChatEvent", "low")
def on_chat(event): def on_chat(event):
sender = event.getPlayer() sender = event.getPlayer()
msg = event.getMessage() msg = event.getMessage()
if sender.hasPermission(ac_permission) and not event.isCancelled(): if sender.hasPermission(ac_permission) and not event.isCancelled():
key = get_key(uid(sender)) if msg[:len(ac_key)] == ac_key:
if sender.getName() in ac_toggle_list: adminchat(sender, msg[1:])
adminchat(sender, msg) event.setCancelled(True)
event.setCancelled(True) elif sender.getName() in ac_toggle_list:
elif msg[:len(key)] == key: adminchat(sender, msg)
adminchat(sender, msg[len(key):]) event.setCancelled(True)
event.setCancelled(True)
-134
View File
@@ -1,134 +0,0 @@
from helpers import *
from traceback import format_exc as print_traceback
import time
an_permission = "utils.an";
notes = open_json_file("adminnotes", [])
continued_messages = {}
def save_notes():
save_json_file("adminnotes", notes)
def r_ago(unit, i):
# Return ago + plural
if i != 1:
unit += "s"
return "%s %s ago" % (i, unit)
def calc_diff(time_ago):
current = time.time()
s = current-time_ago
s = int(s)
ago = "Some time ago"
if s < 10:
ago = "Just now"
elif s >= 10 and s < 60:
ago = r_ago("second", s)
elif s >= 60 and s < 3600:
ago = r_ago("minute", s/60)
elif s >= 3600 and s < 43200:
ago = r_ago("hour", s/60/60)
elif s >= 43200:
ago = r_ago("day", s/60/60/12)
return ago
def show_all_notes(sender):
if len(notes) == 0:
msg(sender, "&aNo open notes at the moment!")
return
for i in range(0, len(notes)):
arr = notes[i]
name = arr[0]
message = arr[1]
note_time = arr[2]
ago = calc_diff(note_time)
msg(sender, "&6#%s - &e%s&6, %s:" % (str(i+1), name, ago))
msg(sender, "&7%s" % colorify(message))
def show_an_help(sender):
msg(sender, "&6AdminNotes Help:")
msg(sender, "&e- /an")
msg(sender, "&7&oLists all notes")
msg(sender, "&e- /an del <ID>")
msg(sender, "&7&oRemove a note")
msg(sender, "&e- /an help")
msg(sender, "&7&oShows this menu")
msg(sender, "&e- /an Some text...")
msg(sender, "&7&oWrite a new note")
msg(sender, "&e- /an This text is very++")
msg(sender, "&7&oContinue writing your note when using &e/an long guys!&7&o again")
@hook.command("an", aliases=["adminnotes", "adminnote"])
def adminnotes_command(sender, command, label, args):
if not sender.hasPermission(an_permission):
noperm(sender)
return
try:
arglen = len(args)
# arg length not valid
if arglen == 0:
show_all_notes(sender)
return
# Shows note help
subcmd = args[0].lower()
if subcmd == "help":
show_an_help(sender)
return
# Delete note
if subcmd == "del":
if arglen != 2:
show_an_help(sender)
return
if not args[1].isdigit():
msg(sender, "&cThe ID has to be numeric (check /an if you're unsure)")
return
note_id = int(args[1])-1
if note_id >= len(notes):
msg(sender, "&cThere is no note with that ID!")
return
# Deletes note by index
del notes[note_id]
save_notes()
msg(sender, "&aSuccessfully deleted note #%s!" % str(note_id+1))
return
message = " ".join(args)
name = sender.getName()
if name in continued_messages:
message = continued_messages[name] + " " + message
del continued_messages[name]
if message[-2:] == "++":
message = message[:-2]
continued_messages[name] = message
msg(sender, "&6You can continue writing by using &e/an <text ...>")
else:
notes.append([name, message, time.time()])
save_notes()
msg(sender, "&eNew note:&6 " + message)
broadcast(an_permission, "&a%s just added a new note! &2Type /an" % name)
except:
error(print_traceback())
@hook.event("player.PlayerJoinEvent", "monitor")
def on_an_join(event):
player = event.getPlayer()
if not player.hasPermission(an_permission):
return
if len(notes) > 0:
msg(player, "&cThere are currently %s open notes!" % len(notes))
elif len(notes) == 0:
msg(player, "&aThere are currently no open notes!")
-137
View File
@@ -1,137 +0,0 @@
from helpers import *
badges = open_json_file("badges", {})
badges_available = {
"helpful" : "A very helpful player",
"expert_minecraft" : "An expert in Minecraft",
"expert_coder" : "A good coder",
"oldtimer" : "A long time player",
"good_builder" : "A very good builder",
"friendly" : "Many think that this player is friendly",
"very_active" : "A very active player",
"trustworthy" : "This player is very trustworthy",
}
badges_perm_add = "utils.badges.add"
badges_perm_del = "utils.badges.delete"
def save_badges():
save_json_file("badges", badges)
def get_badges(player):
sender_id = uid(player)
return badges.get(sender_id, [])
def show_badges(sender, player):
player_badges = get_badges(player)
if player_badges:
msg(sender, "&6Badges of " + player.getName())
for key in player_badges:
msg(sender, "&b> &3&o%s" % badges_available[key])
else:
msg(sender, "&eThis player has no badges yet")
def new_badge_event(player, badge):
msg(player, "")
msg(player, "&6Wow! You just received a badge!")
msg(player, "&b-> &3%s" % badges_available[badge])
msg(player, "&7Type /badge to see all your badges!")
msg(player, "")
player.playSound(player.getLocation(), "random.orb", 1, 1)
def del_badge_event(player, badge):
msg(player, "&cWe took your badge \"%s\"." % badges_available[badge])
def list_badges(sender):
if badges_available:
for key in badges_available.keys():
msg(sender, "&b> &3%s &7&o\"%s\"" % (key, badges_available[key]))
else:
msg(sender, "&cThere are currently no badges available")
def add_badge(sender, target, badge):
if badge in badges_available:
player_badges = get_badges(target)
if badge in player_badges:
msg(sender, "&cThis player got this badge already!")
return
player_badges.append(badge)
if player_badges:
badges[uid(target)] = player_badges
msg(sender, "&aYou just gave %s a new badge!" % target.getName())
new_badge_event(target, badge)
save_badges()
else:
msg(sender, "&cThere is no badge called %s. Check /badge list!" % badge)
def del_badge(sender, target, badge):
if badge in badges_available.keys():
player_badges = get_badges(target)
if badge in player_badges:
player_badges.remove(badge)
badges[uid(target)] = player_badges
msg(sender, "&aYou just took %s from %s!" % (badge, target.getName()))
save_badges()
del_badge_event(target, badge)
return
msg(sender, "&c%s doesn't have this badge!" % target.getName())
else:
msg(sender, "&cThere is no badge called %s. Check /badge list!" % badge)
@hook.command("badge", aliases=["badges", "rewards"])
def on_badge_command(sender, command, label, args):
argnum = int(len(args))
# No arguments
if argnum is 0:
show_badges(sender, sender)
# Length of arguments is 1
if argnum == 1:
# If only argument is "list"
if args[0].lower() == "list":
list_badges(sender)
return True
# If only argument is a player name
target = server.getPlayer(args[0])
if is_player(target):
show_badges(sender, target)
return True
else:
msg(sender, "&cThere is no player called %s online." % args[0])
return True
msg(sender, "&cUnknown syntax: /badge <playername> &o&c /badge list")
return True
# Length of arguments is 3
if argnum == 3:
cmd = args[0].lower()
target = server.getPlayer(args[1])
new_badge = args[2].lower()
if cmd == "add":
if not sender.hasPermission(badges_perm_add):
noperm(sender)
return True
add_badge(sender, target, new_badge)
return True
if cmd == "take" or cmd == "del":
if not sender.hasPermission(badges_perm_del):
noperm(sender)
return True
del_badge(sender, target, new_badge)
return True
msg(sender, "&cUnknown syntax: /badge <add|take> <playername> <badge>")
return True
-164
View File
@@ -1,164 +0,0 @@
from helpers import *
"""
@simplecommand is a decorator which is meant to replace @hook.command in redstoner-utils, where useful.
It takes care of checks such as whether the sender is a player, whether they have permission,
whether there are enough argumens, and also takes care of a help message.
On top of that, it makes the code shorter and easier to write with features like Validate, and returning a message instead of a boolean value.
@simplecommand has an inbuilt tracing feature, so you won't have to put all your code in a try/except statement anymore.
Make sure to `from basecommands import simplecommand` before using this decorator.
The arguments are as follows:
* cmd: the command, self explanatory (required);
* aliases: A list containing any aliases for the command, like shortcuts;
* usage: a String defining the expected arguments for the command. Example:
Let's say I have a command /tp <player_to_teleport> <destination_player>. The usage is: "<player_to_teleport> <destination_player>".
I suggest we use the same format throughout redstoner-utils:
- Separate arguments by spaces;
- Use <> if the argument is required, and [] if the argument is optional;
- Add .. to the argument's identifier (name) if it is for example a message (containing spaces).
for example in /msg, the usage would be "<player> <msg..>"
* description: a description of what the command does. Defaults to "Handles cmd".
This is used for the help message, where the description is (meant to be) indented. To keep this indentation
with longer descriptions, call the help message (with the command, ingame) and add '\n'
when it jumps to a new line in the chat. The decorator will take care of the indentation after that.
* senderLimit: an integer resembling the accepted sender type. Defaults to -1. Use:
-1 for console as well as players;
0 for players only;
1 for console only.
* amin: an integer resembling the minimum amount of arguments. Defaults to 0
* amax: an integer resembling the maximum amount of arguments. Defaults to -1, which means that there is no maximum.
* helpNoargs: a boolean value resembling whether the help message should be displayed when no arguments are given.
Defaults to False.
* helpSubcmd: a boolean value resembling whether the help message should be displayed when the first argument.lower() equals "help".
Defaults to False.
Comments on the function added to the decorator:
It should return a message to send to the player. Color codes are translated automatically. It can return None or an empty string to send nothing.
Returning "HELP" makes it show the help message.
Inside the function, calls to static methods in the class Validate can be used to make the code shorter and easier to write (maybe not easier to read).
For example, to make sure that a condition is met, use Validate.isTrue(condition, message to send to the player if the condition is not met)
Don't forget to `from basecommands import Validate` if you wish to make use of this.
For all other Validate checks, see the code below. Feel free to add your own.
Instead of returning a message mid-code to describe an error, you can also use raise CommandException(msg), but it is almost always possible
to replace this return statement with a call to one of the functions in the Validate class. Once again, if you use raise CommandException(msg),
don't forget to `from basecommands import CommandException`.
"""
to_see_permission = "utils.showpermission" # See cmd permission in help
def isSenderValid(senderLimit, isPlayer):
return True if senderLimit == -1 else senderLimit != isPlayer
def invalidSenderMsg(isPlayer):
return "&cThat command can only be used by " + ("the console" if isPlayer else "players")
def helpMsg(sender, cmd, description, usage, aliases, permission):
help_msg = "&aInformation about command /%s:\n &9%s" % (cmd, description.replace("\n", "\n "))
help_msg += "\n \n&aSyntax: /%s %s" % (cmd, usage)
if aliases:
help_msg += ("\n&6Aliases: " + "".join([(alias + ", ") for alias in aliases]))[:-2]
if sender.hasPermission(to_see_permission):
help_msg += "\n&6Required permission: " + permission
return help_msg
def simplecommand(cmd,
aliases = [],
usage = "[args...]",
description = None,
senderLimit = -1,
amin = 0,
amax = -1,
helpNoargs = False,
helpSubcmd = False):
cmd = cmd.lower()
permission = "utils." + cmd
if not description:
description = "Handles " + cmd
if not usage:
usage = "/%s <subcmd>" % cmd
def getHelp(sender):
return helpMsg(sender, cmd, description, usage, aliases, permission)
def decorator(function):
@hook.command(cmd, aliases = aliases)
def call(sender, command, label, args):
message = run(sender, command, label, args)
if message:
if message == "HELP":
message = getHelp(sender)
msg(sender, message)
return True
def run(sender, command, label, args):
isPlayer = is_player(sender)
if not isSenderValid(senderLimit, isPlayer):
return invalidSenderMsg(isPlayer)
if not sender.hasPermission(permission):
return "&cYou do not have permission to use that command"
if ((not args) and helpNoargs) or (helpSubcmd and args and args[0].lower() == "help"):
return getHelp(sender)
if not checkargs(sender, args, amin, amax):
return None
try:
return function(sender, command, label, args)
except CommandException, e:
return e.message
except Exception, e:
error(trace())
return "&cAn internal error occurred while attempting to perform this command"
return call
return decorator
class CommandException(Exception):
pass
class Validate():
@staticmethod
def notNone(obj, msg):
if obj == None:
raise CommandException(msg)
@staticmethod
def isPlayer(sender):
if not is_player(sender):
raise CommandException("&cThat command can only be run by players")
@staticmethod
def isConsole(sender):
if is_player(sender):
raise CommandException("&cThat command can only be run from the console")
@staticmethod
def isAuthorized(sender, permission, msg = "that command"):
if not sender.hasPermission(permission):
raise CommandException("&cYou do not have permission to use " + msg)
@staticmethod
def isTrue(obj, msg):
if obj != True:
raise CommandException(msg)
@staticmethod
def checkArgs(sender, args, amin, amax):
if not checkargs(sender, args, amin, amax):
raise CommandException("")
-296
View File
@@ -1,296 +0,0 @@
from helpers import *
from basecommands import simplecommand, Validate, CommandException
from time import sleep
from collections import deque
import thread
import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
import org.bukkit.block.Furnace as Furnace
import org.bukkit.inventory.ItemStack as ItemStack
import org.bukkit.Material as Material
import org.bukkit.event.block.Action as Action
import org.bukkit.block.BlockFace as BlockFace
import org.bukkit.scheduler.BukkitRunnable as Runnable
"""
# Permissions:
# - utils.toggle: for use of the command
# - utils.toggle.cauldron
# - utils.toggle.slab
# - utils.toggle.furnace
# - utils.toggle.piston
# - utils.toggle.dropper
# - utils.toggle.hopper
"""
settingInformation = dict( #[setting type, identifying description, detailed description, aliases, (optional) max slot id], setting types: 0 = toggle, default on. 1 = Set your setting to held itemstack, 2 = toggle, default off
cauldron = [0,
"easy cauldron water level control",
"Toggles whether cauldrons auto-fill upon placement and whether right clicking them with redstone dust or empty hand will cycle their water level",
["caul", "water"]
],
slab = [0,
"automatically flipping placed slabs upside-down",
"Toggles whether slabs/steps which you place should be automatically flipped upside-down",
["step"]
],
furnace = [1,
"automatically filling furnaces upon placement",
"Sets your preferred default furnace contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle furnace clear to clear all slots.",
["cooker", "fillf"], 2
],
#torch = [0,
# "removal of torches you place on redstone blocks",
# "Toggles whether redstone torches which you place on redstone blocks will be deleted after a short amount of delay.",
# ["redstonetorch", "tor"]
#],
piston = [2,
"rotating pistons, droppers and hoppers to face the block you place them against",
"Toggles whether pistons or sticky pistons which you place will be rotated to face the block which you placed them against.",
["invert", "rp"]
],
dropper = [1,
"automatically filling droppers upon placement",
"Sets your preferred default dropper contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle dropper clear to clear all slots.",
["itemshooter", "filld"], 8
],
hopper = [1,
"automatically filling hoppers upon placement",
"Sets your preferred default hopper contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle hopper clear to clear all slots.",
["itemtransporter", "fillh"], 4
]
)
defaults = {
0: list,
1: dict,
2: list
}
faces = {
BlockFace.DOWN : 0,
BlockFace.UP : 1,
BlockFace.NORTH : 2,
BlockFace.SOUTH : 3,
BlockFace.WEST : 4,
BlockFace.EAST : 5
}
playerSettings = open_json_file("blockplacemods", {})
for setting, details in settingInformation.iteritems():
if playerSettings.get(setting) == None:
playerSettings[setting] = defaults[details[0]]()
def get(setting):
return playerSettings[setting]
def saveSettings():
save_json_file("blockplacemods", playerSettings)
def getSettingDetails(arg):
try:
arg = arg.lower()
for setting, details in settingInformation.iteritems():
if setting == arg or arg in details[3]:
return (setting, details)
except:
error(trace())
raise CommandException(" &cThat setting could not be found.\n For command help, use &o/toggle &cor &o/set")
@simplecommand("toggle",
aliases = ["setting", "set", "config"],
usage = "<setting> [value|info]",
description = "Toggles or sets your preferences for our redstone \nutilities. The following settings are available:\n" + ", ".join([x for x in settingInformation]),
senderLimit = 0,
helpNoargs = True,
helpSubcmd = True,
amax = 2)
def toggle_command(sender, command, label, args):
setting, details = getSettingDetails(args[0])
Validate.isAuthorized(sender, "utils.toggle." + setting, "that setting")
values = get(setting)
player = server.getPlayer(sender.getName())
uuid = uid(player)
arglen = len(args)
if details[0] in (0,2): # Toggle
default = details[0] == 0 # If True: toggle on if list doesn't contain the uuid
enabled = (uuid not in values) == default #Invert if details[0] == 2 (toggle disabled by default)
new = None
if arglen == 1:
new = not enabled
else:
arg2 = args[1].lower()
if arg2 == "info":
return " &aSetting %s:\n &9%s\n &6Accepted arguments: [on|enable|off|disable|toggle|switch|info]\n &6Aliases: %s" % (setting, details[2], ", ".join(details[3]))
elif arg2 in ("toggle", "switch"):
new = not enabled
elif arg2 in ("on", "enable"):
new = not default
elif arg2 in ("off", "disable"):
new = default
else:
return " &cArgument '%s' was not recognized. \n Use &o/toggle %s info &cfor more information" % (arg2, setting)
if enabled == new:
return " &cAlready %s: &a%s" % ("enabled" if enabled else "disabled", details[1])
if new == default:
values.remove(uuid)
else:
values.append(uuid)
saveSettings()
return (" &aEnabled " if new else " &aDisabled ") + details[1]
elif details[0] == 1: # Save ItemStack in hand
arg2 = args[1].lower() if arglen > 1 else ""
enabled = uuid in values
if arg2 == "clear":
if enabled:
del values[uuid]
return " &aDisabled " + details[1]
if arg2 == "details":
return " &aSetting %s:\n &9%s \n&6Accepted arguments: [<slot>|clear|details]" % (setting, details[2])
slot = int(arg2) if arg2.isdigit() else 0
if not (0 <= slot <= details[4]):
return " &cSlot number must be more than or equal to 0 and less than or equal to %s!" % details[4]
item = fromStack(player.getItemInHand())
if item[0] == 0 or item[1] <= 0:
if enabled:
items = values[uuid]
if slot in items:
del items[slot]
saveSettings()
if len(items) == 0:
del items
return " &aDisabled " + details[1]
return " &aCleared slot %s of setting %s" % (slot, setting)
return " &cSlot %s of setting %s was already cleared!" % (slot, setting)
return " &cAlready disabled: " + details[1]
if arglen == 2 and not arg2.isdigit():
return " &cArgument '%s' was not recognized. \nUse &o/toggle %s details &cfor more detailsrmation." % (arg2, setting)
if not enabled:
values[uuid] = {}
values[uuid][slot] = item
saveSettings()
return ((" &aEnabled setting %s, S" % setting) if len(values[uuid]) == 1 else " &aS") + "et itemstack in slot %s to item in hand" % (slot)
return None #This shouldn't happen
def fromStack(itemStack):
return [itemStack.getTypeId(), itemStack.getAmount(), itemStack.getData().getData()]
def toStack(lst):
return ItemStack(lst[0], lst[1], lst[2])
def isEnabled(toggleSetting, uuid):
return (uuid not in get(toggleSetting)) == (settingInformation[toggleSetting][0] == 0) #Invert if off by default
@hook.event("block.BlockPlaceEvent", "monitor")
def on_block_place(event):
if event.isCancelled():
return
player = event.getPlayer()
if not is_creative(player):
return
uuid = uid(player)
block = event.getBlockPlaced()
material = block.getType()
if (material in (Material.WOOD_STEP, Material.STEP)
and isEnabled("slab", uuid)
and player.hasPermission("utils.toggle.slab")
and block.getData() < 8
):
block.setData(block.getData() + 8) # Flip upside down
elif (material == Material.CAULDRON
and isEnabled("cauldron", uuid)
and player.hasPermission("utils.toggle.cauldron")
):
block.setData(3) #3 layers of water, 3 signal strength
elif ((material == Material.FURNACE and player.hasPermission("utils.toggle.furnace"))
or (material == Material.DROPPER and player.hasPermission("utils.toggle.dropper"))
or (material == Material.HOPPER and player.hasPermission("utils.toggle.hopper"))
):
stacks = get(str(material).lower()).get(uuid)
if stacks != None: # Enabled
state = block.getState()
inv = state.getInventory()
for slot, stack in stacks.iteritems():
inv.setItem(int(slot), toStack(stack))
state.update()
"""
elif (material == Material.REDSTONE_TORCH_ON
and event.getBlockAgainst().getType() == Material.REDSTONE_BLOCK
and isEnabled("torch", uuid)
and player.hasPermission("utils.toggle.torch")
):
torches_to_break.append(block)
"""
if (material in (Material.PISTON_BASE, Material.PISTON_STICKY_BASE)
and isEnabled("piston", uuid)
and player.hasPermission("utils.toggle.piston")
):
block.setData(faces[block.getFace(event.getBlockAgainst())])
@hook.event("player.PlayerInteractEvent", "monitor")
def on_interact(event):
player = event.getPlayer()
if (isEnabled("cauldron", uid(player))
and player.hasPermission("utils.toggle.cauldron")
and is_creative(player)
and event.getAction() == Action.RIGHT_CLICK_BLOCK
and (not event.hasItem() or event.getItem().getType() == Material.REDSTONE)
and event.getClickedBlock().getType() == Material.CAULDRON
):
block = event.getClickedBlock()
event2 = BlockBreakEvent(block, player)
server.getPluginManager().callEvent(event2)
if not event2.isCancelled():
block.setData(block.getData() - 1 if block.getData() > 0 else 3)
"""
break_torches = True
torches_to_break = deque()
def stop_breaking_torches():
break_torches = False
info("Interrupted torch breaking thread")
class torch_breaker(Runnable):
def run():
try:
if break_torches:
for i in range(len(torches_to_break)):
block = torches_to_break.popleft()
mat = block.getType()
if mat == Material.REDSTONE_TORCH_OFF:
block.setTypeId(0)
elif mat == Material.REDSTONE_TORCH_ON:
torches_to_break.append(block)
except:
error(trace())
"""
-110
View File
@@ -1,110 +0,0 @@
from helpers import *
import threading
import time
calc_users = open_json_file("calc", [])
math_operators = ["+", "-", "*", "/", "%", ">", "<", "^", "&", "|"]
allowed_strings = ["0b", "0x", "(", ")", "hex(", "bin(", "abs(", "int(", "min(", "max(", "round(", "float("]
allowed_alpha = ["a", "b", "c", "d", "e", "f"]
calc_perm = "utils.calc"
calc_perm_power = "utils.calc.power"
def calc(sender, text):
try:
return do_calc(sender, text.lower())
except:
return None
def do_calc(sender, text):
"""
extracts a mathematical expression from `text`
returns (expression, result) or None
"""
expression = ""
should_calc = False
i = 0
while True:
if i >= len(text):
break
char = text[i]
if i < len(text) - 5 and str(char + text[i+1] + text[i+2] + text[i+3] + text[i+4] + text[i+5]) in allowed_strings:
expression += char
expression += text[i + 1]
expression += text[i + 2]
expression += text[i + 3]
expression += text[i + 4]
expression += text[i + 5]
i += 5
should_calc = True
elif i < len(text) - 3 and str(char + text[i+1] + text[i+2] + text[i+3]) in allowed_strings:
expression += char
expression += text[i + 1]
expression += text[i + 2]
expression += text[i + 3]
i += 3
should_calc = True
elif i < len(text) - 1 and str(char + text[i + 1]) in allowed_strings:
expression += char
expression += text[i + 1]
i += 1
should_calc = True
elif char.isdigit() or char in allowed_alpha or (expression and char == ".") or (should_calc and char == " ") or (should_calc and char == ","):
expression += char
should_calc = True
elif char in math_operators or char in ["(", ")"]:
# calculation must include at least 1 operator
should_calc = True
expression += char
elif should_calc and char.isalpha():
# don't include any more text in the calculation
break
i += 1
last_char = ' '
for char in expression:
if last_char == '*' and char == '*':
if sender.hasPermission(calc_perm_power):
break
else:
return None
last_char = char
if should_calc:
try:
result = str(eval(expression)) # pylint: disable = W0123
except: # pylint: disable = W0702
# we can run into all kinds of errors here
# most probably SyntaxError
return None
return (expression, result)
return None
def thread_calc(message, sender):
output = calc(sender, message)
if output and sender.isOnline():
msg(sender, "&2=== Calc: &e" + output[0] + " &2= &c" + output[1])
@hook.event("player.AsyncPlayerChatEvent", "monitor")
def on_calc_chat(event):
sender = event.getPlayer()
message = event.getMessage()
if not event.isCancelled() and uid(sender) in calc_users and sender.hasPermission(calc_perm):
thread = threading.Thread(target=thread_calc, args=(message, sender))
thread.daemon = True
thread.start()
@hook.command("calc", description="Toggles chat calculations")
def on_calc_command(sender, command, label, args):
plugin_header(sender, "Chat Calculator")
if not sender.hasPermission(calc_perm):
noperm(sender)
return True
if not checkargs(sender, args, 0, 1):
return True
if not is_player(sender):
msg(sender, "&cYou are not a player!")
return True
toggle(sender, calc_users, name = "Calc")
save_json_file("calc", calc_users)
return True
-319
View File
@@ -1,319 +0,0 @@
############################################
# Alias v2.0 by Pepich #
# Changes to previous version from curs3d: #
# Dynamic alias limit from permissions #
# AC/CG/MSG support #
# Color support #
# Bugfixes #
# #
# TODO: #
# Add command support... #
############################################
import os
import org.bukkit as bukkit
from org.bukkit import *
from helpers import *
from traceback import format_exc as trace
from secrets import *
# Version number and requirements
alias_version = "2.0.0"
helpers_versions = ["1.1.0", "2.0.0"]
enabled = False
error = colorify("&cUnspecified error")
commands_per_page = 5
global_aliases = {"./":"/"}
data = {}
use_mysql = False
# Permissions:
# Grants full access immediately
permission_ALL = "utils.alias.*"
# Access to the command to display the help screen
permission_BASE = "utils.alias"
# Make replacements only when the user has this permission
permission_USE = "utils.alias.use"
# Modify aliases
permission_MODIFY = "utils.alias.modify"
permission_MODIFY_OTHERS = "utils.alias.modify.others"
# List aliases
permission_LIST = "utils.alias.list"
permission_LIST_OTHERS = "utils.alias.list.others"
# Set alias amounts/length limits, e.g. utils.alias.amount.420
permission_AMOUNT = "utils.alias.amount."
permission_LENGTH = "utils.alias.length."
# See when the plugin was disabled due to version errors
permission_INFO = "utils.alias.info"
permission_FINFO = "utils.alias.finfo"
########
# CODE #
########
enabled = helpers_version in helpers_versions
if not enabled:
error = colorify("&6Incompatible versions detected (&chelpers.py&6)")
def safe_open_json(uuid):
if not os.path.exists("plugins/redstoner-utils.py.dir/files/aliases"):
os.makedirs("plugins/redstoner-utils.py.dir/files/aliases")
value = open_json_file("aliases/" + uuid)
if value is None:
value = global_aliases
save_json_file("aliases/" + uuid, value)
return value
@hook.command("alias",
usage="/<command> <add, remove, list, help> [...]",
desc="Allows aliasing of words")
def on_alias_command(sender, cmd, label, args):
try:
args = array_to_list(args)
if not enabled:
disabled_fallback(sender)
return True
if not hasPerm(sender, permission_BASE):
plugin_header(recipient=sender, name="Alias")
noperm(sender)
return True
return subcommands[args[0].lower()](sender, args[1:])
except:
return subcommands["help"](sender, "1")
def help(sender, args):
commands = [colorify("&e/alias help [page]")]
if hasPerm(sender, permission_LIST):
commands += [colorify("&e/alias list &7- Lists all your aliases")]
if hasPerm(sender, permission_MODIFY):
commands += [colorify("&e/alias add <word> <alias> &7- Add an alias")]
commands += [colorify("&e/alias remove <word> &7- Remove an alias")]
if can_remote(sender):
while len(commands) < commands_per_page:
commands += [""]
commands += [colorify("&7Following commands will be executed on <player> yet all output will be redirected to you, except when you set silent to false, then <player> will see it too.")]
if hasPerm(sender, permission_LIST_OTHERS):
commands += [colorify("&e/alias player <name> list [silent]")]
if hasPerm(sender, permission_MODIFY_OTHERS):
commands += [colorify("&e/alias player <name> add <word> <alias> [silent]")]
commands += [colorify("&e/alias player <name> remove <word> [silent]")]
pages = (len(commands)-1)/commands_per_page + 1
page = 1
if len(args) != 0:
page = int(args[0])
if (page > pages):
page = pages
if page < 1:
page = 1
msg(sender, colorify("&e---- &6Help &e-- &6Page &c" + str(page) + "&6/&c" + str(pages) + " &e----"))
page -= 1
to_display = commands[5*page:5*page+5]
for message in to_display:
msg(sender, message)
if page+1 < pages:
msg(sender, colorify("&6To display the next page, type &c/help " + str(page+2)))
return True
@hook.event("player.PlayerJoinEvent", "high")
def on_join(event):
try:
if enabled:
t = threading.Thread(target=load_data, args=(uid(event.getPlayer()), ))
t.daemon = True
t.start()
else:
if event.getPlayer().hasPermission(permission_FINFO):
disabled_fallback(event.getPlayer())
except:
print(trace())
@hook.event("player.AsyncPlayerChatEvent", "high")
def on_player_chat(event):
try:
if enabled:
if event.isCancelled():
return
if not hasPerm(event.getPlayer(), permission_USE):
return
for alias, value in data[str(uid(event.getPlayer()))].items():
if not event.getPlayer().hasPermission(permission_ALL) and len(event.getMessage()) > int(get_permission_content(event.getPlayer(), permission_LENGTH)):
event.setCanceled(True)
plugin_header(event.getPlayer, "Alias")
msg(event.getPlayer(), "The message you wanted to generate would exceed your limit. Please make it shorter!")
return
if event.getPlayer().hasPermission("essentials.chat.color"):
event.setMessage(event.getMessage().replace(colorify(alias), colorify(value)))
else:
event.setMessage(event.getMessage().replace(alias, value))
except:
return
def hasPerm(player, permission):
return (player.hasPermission(permission)) or (player.hasPermission(permission_ALL))
def disabled_fallback(receiver):
if not hasPerm(receiver, permission_INFO):
msg(receiver, colorify("&cUnknown command. Use &e/help&c, &e/plugins &cor ask a mod."))
else:
msg(receiver, colorify("&cPlugin alias v" + alias_version + " has experienced an &eEMERGENCY SHUTDOWN:"))
msg(receiver, error)
msg(receiver, colorify("&cPlease contact a dev/admin (especially pep :P) about this to take a look at it."))
def can_remote(player):
return hasPerm(player, permission_LIST_OTHERS) or hasPerm(player, permission_MODIFY_OTHERS)
def add(sender, args):
plugin_header(sender, "Alias")
if not sender.hasPermission(permission_ALL) and len(data[uid(sender)]) >= int(get_permission_content(sender, permission_AMOUNT)):
msg(sender, "&cCould not create alias: Max_limit reached!")
return True
args = [args[0]] + [" ".join(args[1:])]
data[str(uid(sender))][str(args[0])] = args[1]
save_data(uid(sender))
msg(sender, colorify("&7Alias: ") + args[0] + colorify("&7 -> " + args[1] + colorify("&7 was succesfully created!")), usecolor=sender.hasPermission("essentials.chat.color"))
return True
def radd(sender, args):
args = [args[0:1]] + [" ".join([args[2:len(args)-2]])] + [args[len(args)-1]]
plugin_header(sender, "Alias")
if args[3].lower() == "false":
plugin_header(target, "Alias")
msg(target, "&cPlayer " + sender_name + " &cis creating an alias for you!")
if not sender.hasPermission(permission_ALL) and len(data[uid(sender)]) >= int(get_permission_content(target, permission_AMOUNT)):
msg(sender, "&cCould not create alias: Max_limit reached!")
if args[3].lower() == "false":
msg(target, "&cCould not create alias: Max_limit reached!")
return True
target = get_player(args[0])
if is_player(sender):
sender_name = colorify(sender.getDisplayName)
else:
sender_name = colorify("&6Console")
if len(args) == 3:
args += ["true"]
data[str(uid(target))][str(args[1])] = str(args[2])
save_data(uid(target))
msg(sender, colorify("&7Alias: ") + args[1] + colorify("&7 -> " + args[2] + colorify("&7 was succesfully created!")), usecolor=target.hasPermission("essentials.chat.color"))
if args[3].lower() == "false":
msg(target, colorify("&7Alias: ") + args[1] + colorify("&7 -> " + args[2] + colorify("&7 was succesfully created!")), usecolor=target.hasPermission("essentials.chat.color"))
return True
def remove(sender, args):
plugin_header(sender, "Alias")
try:
msg(sender, colorify("&7Successfully removed alias ") + args[0] + colorify(" &7-> ") + data[uid(sender)].pop(args[0]) + colorify("&7!"), usecolor=sender.hasPermission("essentials.chat.color"))
save_data(uid(sender))
except:
msg(sender, colorify("&cCould not remove alias ") + args[0] + colorify(", it does not exist."), usecolor=sender.hasPermission("essentials.chat.color"))
return True
def rremove(sender, args):
plugin_header(sender, "Alias")
target = get_player(args[0])
if is_player(sender):
sender_name = colorify(sender.getDisplayName)
else:
sender_name = colorify("&6Console")
if args[2].lower() == "false":
print("WTF")
plugin_header(target, "Alias")
msg(target, "&cPlayer " + sender_name + " &cis removing an alias for you!")
try:
alias = data[uid(target)].pop(args[1])
msg(sender, colorify("&7Successfully removed alias ") + args[1] + colorify(" &7-> ") + alias + colorify("&7!"), usecolor=sender.hasPermission("essentials.chat.color"))
if args[2].lower() == "false":
msg(target, colorify("&7Successfully removed alias ") + args[1] + colorify(" &7-> ") + alias + colorify("&7!"), usecolor=sender.hasPermission("essentials.chat.color"))
save_data(uid(target))
except:
msg(sender, colorify("&cCould not remove alias ") + args[1] + colorify(", it does not exist."), usecolor=sender.hasPermission("essentials.chat.color"))
if args[2].lower() == "false":
msg(target, colorify("&cCould not remove alias ") + args[1] + colorify(", it does not exist."), usecolor=sender.hasPermission("essentials.chat.color"))
return True
def list_alias(sender, args):
plugin_header(sender, "Alias")
msg(sender, "&7You have a total of " + str(len(data[uid(sender)])) + " aliases:")
for word, alias in data[str(uid(sender))].items():
msg(sender, colorify("&7") + word + colorify("&7 -> ") + alias, usecolor=sender.hasPermission("essentials.chat.color"))
return True
def rlist_alias(sender, args):
plugin_header(sender, "Alias")
target = get_player(args[0])
if is_player(sender):
sender_name = colorify(sender.getDisplayName)
else:
sender_name = colorify("&6Console")
if len(args) == 1:
args += ["true"]
msg(sender, "Player " + args[0] + " has following aliases (" + str(len(data[uid(target)])) + " in total):")
if args[1].lower() == "false":
plugin_header(target, "Alias")
msg(target, "&cPlayer " + sender_name + " &cis listing your aliases (" + str(len(data[uid(target)])) + " in total):")
for word, alias in data[str(uid(target))].items():
msg(sender, colorify("&7") + word + colorify("&7 -> ") + alias, usecolor=target.hasPermission("essentials.chat.color"))
if args[1].lower() == "false":
msg(target, colorify("&7") + word + colorify("&7 -> ") + alias, usecolor=target.hasPermission("essentials.chat.color"))
return True
def remote(sender, args):
try:
return remotes[args[1].lower()](sender, [args[0]] + [args[2:]])
except:
return subcommands["help"](sender, ["2"])
def load_data(uuid):
if use_mysql:
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("SELECT alias FROM alias WHERE uuid = ?", (uuid, ))
results = curs.fetchall()
if len(results) == 0:
results = global_aliases
curs.execute("INSERT INTO alias VALUES (?,?)", (uuid, results, ))
data[uuid] = results
else:
data[uuid] = safe_open_json(uuid)
def save_data(uuid):
if use_mysql:
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("UPDATE alias SET alias = ? WHERE uuid = ?", (data[uuid], uuid, ))
else:
save_json_file("aliases/" + uuid, data[uuid])
# Subcommands:
subcommands = {
"help": help,
"add": add,
"remove": remove,
"player": remote,
"list": list_alias
}
remotes = {
"add": radd,
"remove": rremove,
"list": rlist_alias,
}
+67 -112
View File
@@ -1,137 +1,92 @@
#pylint: disable = F0401 #pylint: disable = F0401
from helpers import * from helpers import *
from basecommands import simplecommand
from java.util.UUID import fromString as juuid from java.util.UUID import fromString as juuid
from traceback import format_exc as trace
groups = open_json_file("chatgroups", {}) groups = open_json_file("chatgroups", {})
cg_defaultkey = ":" cg_key = ":"
cg_keys = open_json_file("chatgroup_keys", {})
cg_toggle_list = [] cg_toggle_list = []
def get_key(uuid):
key = cg_keys.get(uuid)
return key if key != None else cg_defaultkey
@hook.command("chatgroup") @hook.command("chatgroup")
def on_chatgroup_command(sender, command, label, args): def on_chatgroup_command(sender, args):
plugin_header(sender, "ChatGroups") plugin_header(sender, "ChatGroups")
sender_id = uid(sender) sender_id = uid(sender)
if len(args) == 1 and args[0] == "leave": if len(args) == 1 and args[0] == "leave":
if sender_id in groups.keys(): if sender_id in groups.keys():
groupchat(sender, "left the group", True) groupchat(sender, "left the group", True)
if sender in cg_toggle_list: group = groups[sender_id]
cg_toggle_list.remove(p) del(groups[sender_id])
group = groups[sender_id] save_groups()
del(groups[sender_id])
save_groups()
else:
msg(sender, "&aYou can't leave no group, derp!")
elif len(args) == 1 and args[0] == "info":
if sender_id in groups.keys():
group = groups[sender_id]
msg(sender, "&aCurrent chatgroup: %s" % group)
users = [user.getDisplayName() for user in [server.getPlayer(juuid(uuid)) for uuid, ugroup in groups.iteritems() if ugroup == group] if user]
msg(sender, "&aUsers in this group:")
msg(sender, "&a%s" % ", ".join(users))
else:
msg(sender, "&aYou're in no chatgroup.")
elif len(args) == 2 and args[0] == "join":
groups[sender_id] = args[1]
groupchat(sender, "joined the group", True)
save_groups()
msg(sender, "&aYour chatgroup is set to '%s'" % args[1])
msg(sender, "&aUse chat like '&e%s<message>' to send messages to this group." % get_key(sender_id))
elif len(args) == 1 and args[0] == "key":
msg(sender, "&aYour chatgroup key is currently: '&c%s&a'" % get_key(sender_id))
elif len(args) == 1 and args[0] == "tpahere":
if sender_id in groups.keys():
do_for_chatgroup(groups[sender_id], send_tpa_request, sender)
msg(sender, "&aSent a tpahere request to all users in your chatgroup")
else:
msg(sender, "&cYou have to be in a chatgroup to do that")
else: else:
msg(sender, "&e/chatgroup join <name>") msg(sender, "&aYou can't leave no group, derp!")
msg(sender, "&e/chatgroup leave") elif len(args) == 1 and args[0] == "info":
msg(sender, "&e/chatgroup info") if sender_id in groups.keys():
msg(sender, "&e/chatgroup key") group = groups[sender_id]
msg(sender, "&e/chatgroup tpahere") msg(sender, "&aCurrent chatgroup: %s" % group)
users = []
for uuid, ugroup in groups.iteritems():
if ugroup == group:
usr = server.getPlayer(juuid(uuid))
if usr:
users.append(usr.getDisplayName())
msg(sender, "&aUsers in this group:")
msg(sender, "&a%s" % ", ".join(users))
else:
msg(sender, "&aYou're in no chatgroup.")
elif len(args) == 2 and args[0] == "join":
groups[sender_id] = args[1]
groupchat(sender, "joined the group", True)
save_groups()
msg(sender, "&aYour chatgroup is set to '%s'" % args[1])
msg(sender, "&aUse chat like '&e%s<message>' to send messages to this group." % cg_key)
else:
msg(sender, "&e/chatgroup join <name>")
msg(sender, "&e/chatgroup leave")
msg(sender, "&e/chatgroup info")
@hook.command("cgt") @hook.command("cgt")
def on_cgt_command(sender, command, label, args): def on_cgt_command(sender, args):
p = uid(sender) p = uid(sender)
if p in cg_toggle_list: if p in cg_toggle_list:
cg_toggle_list.remove(p) cg_toggle_list.remove(p)
msg(sender, "&8[&bCG&8] &e&oCG toggle: off") msg(sender, "&8[&bCG&8] &e&oCG toggle: off")
else: else:
cg_toggle_list.append(p) cg_toggle_list.append(p)
msg(sender, "&8[&bCG&8] &e&oCG toggle: on") msg(sender, "&8[&bCG&8] &e&oCG toggle: on")
return True return True
def groupchat(sender, message, ann = False): def groupchat(sender, message, ann = False):
group = groups.get(uid(sender)) group = groups.get(uid(sender))
if group == None: if group == None:
msg(sender, "&cYou are not in a group!") msg(sender, "&cYou are not in a group!")
return return
name = sender.getDisplayName() name = sender.getDisplayName()
if ann: if ann:
mesg = "&8[&bCG&8] &e&o%s&e&o %s" % (name, message) mesg = "&8[&bCG&8] &e&o%s&e&o %s" % (name, message)
else: else:
mesg = "&8[&bCG&8] &f%s&f: &6%s" % (name, message) mesg = "&8[&bCG&8] &f%s&f: &6%s" % (name, message)
mesg = colorify(mesg) info("[ChatGroups] %s (%s): %s" % (sender.getDisplayName(), group, message))
for receiver in server.getOnlinePlayers():
groups.get(uid(receiver)) == group and msg(receiver, mesg)
info("[ChatGroups] %s (%s): %s" % (sender.getDisplayName(), group, message))
do_for_chatgroup(group, msg, mesg, usecolor = False)
def do_for_chatgroup(group, func, *args, **kwargs):
for receiver in server.getOnlinePlayers():
if groups.get(uid(receiver)) == group:
func(receiver, args, kwargs)
def send_tpa_request(receiver, sender):
if not receiver == sender:
runas(sender, "/tpahere " + receiver.getName())
def save_groups(): def save_groups():
save_json_file("chatgroups", groups) save_json_file("chatgroups", groups)
@hook.event("player.AsyncPlayerChatEvent", "normal") @hook.event("player.AsyncPlayerChatEvent", "normal")
def on_chat(event): def on_chat(event):
sender = event.getPlayer() sender = event.getPlayer()
msge = event.getMessage() msge = event.getMessage()
if not event.isCancelled(): if not event.isCancelled():
sender_id = uid(sender) sender_id = uid(sender)
key = get_key(sender_id) if msge[:len(cg_key)] == cg_key and sender_id in groups.keys():
keylen = len(key) groupchat(sender, msge[1:])
if msge[:keylen] == key and sender_id in groups.keys(): event.setCancelled(True)
groupchat(sender, msge[keylen:]) elif sender_id in cg_toggle_list:
event.setCancelled(True) groupchat(sender, msge)
elif sender_id in cg_toggle_list: event.setCancelled(True)
groupchat(sender, msge)
event.setCancelled(True)
@simplecommand("chatgroupkey",
aliases = ["cgkey"],
senderLimit = 0,
helpNoargs = True,
helpSubcmd = True,
description = "Sets a key character for chatting to your chatgroup",
usage = "<key>")
def chatgroupkey_command(sender, command, label, args):
key = " ".join(args)
uuid = uid(sender)
if key.lower() == "default" or key == cg_defaultkey:
del cg_keys[uuid]
save_keys()
return "&aYour chatgroup key was set to the default character: '&c%s&a'" % cg_defaultkey
cg_keys[uid(sender)] = key
save_keys()
return "&aYour chatgroup key was set to: '&c%s&a'" % key
def save_keys():
save_json_file("chatgroup_keys", cg_keys)
-95
View File
@@ -1,95 +0,0 @@
import json
import urllib2
import datetime
import mysqlhack #pylint: disable = unused-import
from traceback import format_exc as print_traceback
from com.ziclix.python.sql import zxJDBC
from secrets import *
from helpers import *
# receive info based on the user's IP. information provided by ipinfo.io
def ip_info(player):
if player.isOnline():
return json.load(urllib2.urlopen("http://ipinfo.io%s/json" % str(player.getAddress().getAddress())))
else:
return {}
# receive first join date based on the player data (may not be accurate)
def get_first_join(player):
first_join = int(player.getFirstPlayed())
dt = datetime.datetime.fromtimestamp(first_join/1000.0)
return dt.strftime("%Y-%m-%d %H:%M")
# receive last seen date based on the player data
def get_last_seen(player):
last_seen = int(player.getLastPlayed())
dt = datetime.datetime.fromtimestamp(last_seen/1000.0)
return dt.strftime("%Y-%m-%d %H:%M")
# receive link and email from website
def get_website_data(player):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
uuid = str(uid(player)).replace("-", "")
curs.execute("SELECT DISTINCT `id`, `email` FROM users WHERE `uuid` = ? LIMIT 1", (uuid,))
results = curs.fetchall()
curs.close()
conn.close()
return ("http://redstoner.com/users/%s" % results[0][0], results[0][1]) if results else (None, None)
# receive country based on the user's IP
def get_country(data):
return str(data.get("country"))
def get_all_names(player):
uuid = str(uid(player)).replace("-", "")
names = json.load(urllib2.urlopen("https://api.mojang.com/user/profiles/%s/names" % uuid))
# [ {"name": "some_name"}, {"name": "other_name"} ]
return ", ".join([name["name"] for name in names])
# combines data
def get_all_data(sender, player):
data = ip_info(player)
msg(sender, "")
try:
msg(sender, "&7 -- Data provided by Redstoner")
msg(sender, "&6> UUID: &e%s" % str(uid(player)))
msg(sender, "&6> First joined: &7(y-m-d h:m:s) &e%s" % get_first_join(player))
msg(sender, "&6> Last seen: &7(y-m-d h:m:s) &e%s" % get_last_seen(player))
website = get_website_data(player)
msg(sender, "&6> Website account: &e%s" % website[0])
msg(sender, "&6> email: &e%s" % website[1])
msg(sender, "&7 -- Data provided by ipinfo.io")
msg(sender, "&6> Country: &e%s" % get_country(data))
msg(sender, "&7 -- Data provided by Mojang")
msg(sender, "&6> All ingame names used so far: &e%s" % get_all_names(player))
except:
# can throw exceptions such as timeouts when Mojang API is down
warn(print_traceback())
msg(sender, "&cSorry, something went wrong while fetching data")
@hook.command("check", description="Displays useful stuff about a user", usage="/check <player>")
def on_hook_command(sender, command, label, args):
if sender.hasPermission("utils.check"):
if not checkargs(sender, args, 1, 1):
return True
plugin_header(sender, "Check")
msg(sender, "&7Please notice that the data may not be fully accurate!")
player = server.getOfflinePlayer(args[0]) if len(args) > 0 else None
t = threading.Thread(target=get_all_data, args=(sender, player))
t.daemon = True
t.start()
else:
msg(sender, "&4You don't have the required permissions to execute this command!")
return True
+47 -47
View File
@@ -4,47 +4,47 @@ no_cyclers = open_json_file("cycle", [])
@hook.command("cycle") @hook.command("cycle")
def on_cycler_command(sender, command, label, args): def on_cycler_command(sender, args):
plugin_header(sender, "Cycle") plugin_header(sender, "Cycle")
if not is_player(sender): if not is_player(sender):
msg(sender, "&conly players can do this") msg(sender, "&conly players can do this")
return True
if not len(args) == 1:
msg(sender, "&cUsage: /cycle <on|off>")
return True
cmd = args[0].lower()
pid = uid(sender)
nop = pid in no_cyclers
if cmd == "on":
if nop:
no_cyclers.remove(pid)
save_cyclers()
msg(sender, "&aTurned &2on&a inventory cycling!")
else:
msg(sender, "&aAlready turned on.")
elif cmd == "off":
if not nop:
no_cyclers.append(pid)
save_cyclers()
msg(sender, "&aTurned &coff&a inventory cycling!")
else:
msg(sender, "&aAlready turned off.")
else:
msg(sender, "&cUsage: /cycle <on|off>")
return True return True
if not len(args) == 1:
msg(sender, "&cUsage: /cycle <on|off>")
return True
cmd = args[0].lower()
pid = uid(sender)
nop = pid in no_cyclers
if cmd == "on":
if nop:
no_cyclers.remove(pid)
save_cyclers()
msg(sender, "&aTurned &2on&a inventory cycling!")
else:
msg(sender, "&aAlready turned on.")
elif cmd == "off":
if not nop:
no_cyclers.append(pid)
save_cyclers()
msg(sender, "&aTurned &coff&a inventory cycling!")
else:
msg(sender, "&aAlready turned off.")
else:
msg(sender, "&cUsage: /cycle <on|off>")
return True
@hook.event("player.PlayerItemHeldEvent", "normal") @hook.event("player.PlayerItemHeldEvent", "normal")
def on_slot_change(event): def on_slot_change(event):
player = event.getPlayer() player = event.getPlayer()
if is_creative(player) and uid(player) not in no_cyclers and not player.isSneaking(): if is_creative(player) and uid(player) not in no_cyclers and not player.isSneaking():
prev_slot = event.getPreviousSlot() prev_slot = event.getPreviousSlot()
new_slot = event.getNewSlot() new_slot = event.getNewSlot()
if (prev_slot == 0 and new_slot == 8): # left -> right if (prev_slot == 0 and new_slot == 8): # left -> right
do_cycle(player, True) do_cycle(player, True)
elif (prev_slot == 8 and new_slot == 0): # right -> left elif (prev_slot == 8 and new_slot == 0): # right -> left
do_cycle(player, False) do_cycle(player, False)
# ITEM SLOTS # # ITEM SLOTS #
#_____________________________ #_____________________________
@@ -55,16 +55,16 @@ def on_slot_change(event):
# | 0| 1| 2| 3| 4| 5| 6| 7| 8| # | 0| 1| 2| 3| 4| 5| 6| 7| 8|
def do_cycle(player, down): def do_cycle(player, down):
inv = player.getInventory() inv = player.getInventory()
items = inv.getContents() items = inv.getContents()
shift = -9 if down else 9 shift = -9 if down else 9
shift = shift % len(items) shift = shift % len(items)
for _ in range(4): for _ in range(4):
items = items[shift:] + items[:shift] # shift "around" items = items[shift:] + items[:shift] # shift "around"
uniq_items = sorted(set(list(items)[:9])) # get unique inventory uniq_items = sorted(set(list(items)[:9])) # get unique inventory
if uniq_items != [None]: # row not empty if uniq_items != [None]: # row not empty
break break
inv.setContents(items) inv.setContents(items)
def save_cyclers(): def save_cyclers():
save_json_file("cycle", no_cyclers) save_json_file("cycle", no_cyclers)
+74 -102
View File
@@ -5,147 +5,119 @@ import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
inputs = open_json_file("damnspam", {}) # format "x;y;z;World" inputs = open_json_file("damnspam", {}) # format "x;y;z;World"
accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON", "LEVER"] accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON", "LEVER"]
changing_input = False
removing_input = False
def save_inputs(): def save_inputs():
save_json_file("damnspam", inputs) save_json_file("damnspam", inputs)
def location_str(block): def location_str(block):
return ";".join([block.getWorld().getName(), str(block.getX()), str(block.getY()), str(block.getZ())]) return ";".join([block.getWorld().getName(), str(block.getX()), str(block.getY()), str(block.getZ())])
def add_input(creator, block, timeout_off, timeout_on): def add_input(creator, block, timeout_off, timeout_on):
inputs[location_str(block)] = { inputs[location_str(block)] = {
"creator" : uid(creator), "creator" : uid(creator),
"timeout_off" : timeout_off, "timeout_off" : timeout_off,
"timeout_on" : timeout_on, "timeout_on" : timeout_on,
"last_time" : 0 "last_time" : 0
} }
@hook.command("damnspam") @hook.command("damnspam")
def on_dammnspam_command(sender, command, label, args): def on_dammnspam_command(sender, args):
global changing_input plugin_header(sender, "DamnSpam")
if len(args) in [1,2]:
plugin_header(sender, "DamnSpam")
if not checkargs(sender, args, 1, 2):
msg(sender, "&c/damnspam <seconds> &e(Buttons/Levers)")
msg(sender, "&c/damnspam <seconds after off> <seconds after on> &e(Levers only)")
return True
#Gittestlol
if not is_creative(sender): if not is_creative(sender):
msg(sender, "&cYou can only do this in Creative mode.") msg(sender, "&cYou can only do this in Creative mode.")
return True return True
# /damnspam <secs> # /damnspam <secs>
if len(args) == 1: if len(args) == 1:
timeout_on = args[0] timeout_on = args[0]
try: try:
timeout_on = round(float(timeout_on), 2) timeout_on = round(float(timeout_on), 2)
timeout_off = timeout_on timeout_off = timeout_on
if 60 >= timeout_on <= -2 or timeout_on == 0: if not 0 <= timeout_on <= 60:
timeout_on = False msg(sender, "&cThe timeout must be within 0-60.")
if timeout_on == False: return True
msg(sender, "&cThe timeout must be within 0-60 or -1.") except ValueError:
return True msg(sender, "&cThe timeout must be a number")
except ValueError: return True
msg(sender, "&cThe timeout must be a number")
return True
# /damnspam <off> <on> # /damnspam <off> <on>
elif len(args) == 2: elif len(args) == 2:
timeout_on = args[0] timeout_on = args[0]
timeout_off = args[1] timeout_off = args[1]
try: try:
timeout_on = round(float(timeout_on), 2) timeout_on = round(float(timeout_on), 2)
timeout_off = round(float(timeout_off), 2) timeout_off = round(float(timeout_off), 2)
if 60 >= timeout_on <= -2 or timeout_on == 0: if not 0 <= timeout_on <= 60 or not 0 <= timeout_off <= 60:
timeout_on = False msg(sender, "&cThe timeout must be within 0-60.")
if 60 >= timeout_off <= -2 or timeout_off == 0: return True
timeout_off = False except ValueError:
if timeout_on == False or timeout_off == False: msg(sender, "&cThe timeout must be a number")
msg(sender, "&cThe timeout must be within 0-60 or -1.") return True
return True
except ValueError:
msg(sender, "&cThe timeout must be a number")
return True
# get the block we're looking at # get the block we're looking at
target = sender.getTargetBlock(None, 10) target = sender.getTargetBlock(None, 10)
ttype = str(target.getType()) ttype = str(target.getType())
if ttype not in accepted_inputs: if ttype not in accepted_inputs:
msg(sender, "&cPlease look at a button or lever while executing this command!") msg(sender, "&cPlease look at a button or lever while executing this command!")
return True return True
if location_str(target) in inputs:
changing_input = True # this input already has a timeout
# test if player is allowed to build here
test_event = BlockBreakEvent(target, sender) test_event = BlockBreakEvent(target, sender)
server.getPluginManager().callEvent(test_event) server.getPluginManager().callEvent(test_event)
changing_input = False
if test_event.isCancelled(): if test_event.isCancelled():
msg(sender, "&cYou are not allowed to modify this %s" % str(target.getType()).lower()) msg(sender, "&cYou are not allowed to modify this button")
return True return True
# add block to inputs # add block to inputs
add_input(sender, target, timeout_off, timeout_on) add_input(sender, target, timeout_off, timeout_on)
save_inputs() save_inputs()
msg(sender, "&aSuccessfully set a timeout for this %s." % ttype.lower().replace("_", " ")) msg(sender, "&aSuccessfully set a timeout for this %s." % ttype.lower())
return True return True
else:
msg(sender, "&c/damnspam <seconds> &e(Buttons/Levers)")
msg(sender, "&c/damnspam <seconds after off> <seconds after on> &e(Levers only)")
@hook.event("block.BlockBreakEvent", "normal") @hook.event("block.BlockBreakEvent", "normal")
def on_block_break(event): def on_block_break(event):
global removing_input sender = event.getPlayer()
block = event.getBlock()
if removing_input: if str(block.getType()) in accepted_inputs and not event.isCancelled():
return pos_str = location_str(block)
sender = event.getPlayer() if inputs.get(pos_str):
block = event.getBlock() plugin_header(sender, "DamnSpam")
btype = str(block.getType()).lower() if sender.isSneaking():
if str(block.getType()) in accepted_inputs and not event.isCancelled(): inputs.pop(pos_str) # remove
pos_str = location_str(block) save_inputs()
if inputs.get(pos_str): msg(sender, "&eSuccessfully removed the input!")
if sender.isSneaking(): return True
# test if player is allowed to build here else:
removing_input = True event.setCancelled(True)
test_event = BlockBreakEvent(block, sender) msg(sender, "&cYou cannot destroy this input!")
server.getPluginManager().callEvent(test_event) msg(sender, "&c&nSneak&c and break if you want to remove it.")
removing_input = False return True
if test_event.isCancelled():
event.setCancelled(True)
msg(sender, "&cYou are not allowed to remove this %s" % btype)
return True
inputs.pop(pos_str) # remove
save_inputs()
msg(sender, "&eSuccessfully removed this %s!" % btype)
return True
elif not changing_input:
event.setCancelled(True)
msg(sender, "&cYou cannot destroy this %s!" % btype)
msg(sender, "&c&nSneak&c and break if you want to remove it.")
return True
@hook.event("player.PlayerInteractEvent", "normal") @hook.event("player.PlayerInteractEvent", "normal")
def on_interact(event): def on_interact(event):
if (str(event.getAction()) == "RIGHT_CLICK_BLOCK") and not event.isCancelled(): if (str(event.getAction()) == "RIGHT_CLICK_BLOCK") and not event.isCancelled():
sender = event.getPlayer() sender = event.getPlayer()
block = event.getClickedBlock() block = event.getClickedBlock()
btype = str(block.getType()).lower() btype = str(block.getType()).lower()
powered = (block.getData() & 0x8) == 0x8 if btype == "lever" else False # data > 7, but this is how bukkit does it powered = (block.getData() & 0x8) == 0x8 if btype == "lever" else False # data > 7, but this is how bukkit does it
pos_str = location_str(block) pos_str = location_str(block)
data = inputs.get(pos_str) data = inputs.get(pos_str)
if data: if data:
checktime = data["timeout_on"] if powered else data["timeout_off"] checktime = data["timeout_on"] if powered else data["timeout_off"]
if checktime == -1: if data["last_time"] + checktime > now():
event.setCancelled(True) event.setCancelled(True)
msg(sender, "&cThis %s is locked permanently by /damnspam." % (btype)) plugin_header(sender, "DamnSpam")
elif data["last_time"] + checktime > now(): msg(sender, "&cThis %s has a timeout of %ss." % (btype, checktime))
event.setCancelled(True) else:
msg(sender, "&cThis %s has a damnspam timeout of %ss." % (btype, checktime)) inputs[pos_str]["last_time"] = round(now(), 2)
else:
inputs[pos_str]["last_time"] = round(now(), 2)
+130 -134
View File
@@ -1,5 +1,4 @@
#pylint: disable = F0401 #pylint: disable = F0401
import thread
from helpers import * from helpers import *
from org.bukkit.util import Vector from org.bukkit.util import Vector
from math import sin from math import sin
@@ -17,131 +16,128 @@ whitelists = {} # {ff_owner_id: [white, listed, ids]} (Adding file usage later,
@hook.command("forcefield") @hook.command("forcefield")
def on_forcefield_command(sender, command, label, args): def on_forcefield_command(sender, args):
if not is_player(sender) or not sender.hasPermission(ff_perm): if not is_player(sender) or not sender.hasPermission(ff_perm):
noperm(sender) noperm(sender)
return True
if not args or args[0].upper() in ["ON", "OFF"]: # Toggle
forcefield_toggle(sender, args[:1])
return True
args[0] = args[0].upper() # If it gets to this point, there are argument(s).
if args[0] in ["WHITELIST", "WL", "WLIST"]: # Whitelist commands
if not args[1:] or args[1].upper() == "LIST":
thread.start_new_thread(whitelist_list, (sender,))
return True
args[1] = args[1].upper() # If it gets too this point, there is a second argument.
if args[1] == "CLEAR":
whitelist_clear(sender)
elif args[1] in ["ADD", "+"]:
change_whitelist(sender, True, args[2:])
elif args[1] in ["REMOVE", "DELETE", "REM", "DEL", "-"]:
change_whitelist(sender, False, args[2:])
else:
forcefield_header(sender, "&cInvalid syntax. Use &e/ff ? &cfor info.")
elif args[0] in ["HELP", "?"]: # /forcefield help
forcefield_help(sender)
else:
forcefield_header(sender, "&cInvalid syntax. Use &e/ff ? &cfor info.")
return True return True
if not args or args[0].upper() in ["ON", "OFF"]: # Toggle
forcefield_toggle(sender, args[:1])
return True
args[0] = args[0].upper() # If it gets to this point, there are argument(s).
if args[0] in ["WHITELIST", "WL", "WLIST"]: # Whitelist commands
if not args[1:] or args[1].upper() == "LIST":
whitelist_list(sender)
return True
args[1] = args[1].upper() # If it gets too this point, there is a second argument.
if args[1] == "CLEAR":
whitelist_clear(sender)
elif args[1] in ["ADD", "+"]:
change_whitelist(sender, True, args[2:])
elif args[1] in ["REMOVE", "DELETE", "REM", "DEL", "-"]:
change_whitelist(sender, False, args[2:])
else:
forcefield_header(sender, "&cInvalid syntax. Use &e/ff ? &cfor info.")
elif args[0] in ["HELP", "?"]: # /forcefield help
forcefield_help(sender)
else:
forcefield_header(sender, "&cInvalid syntax. Use &e/ff ? &cfor info.")
return True
def change_whitelist(sender, add, names): #Add names if add == True else Remove names. def change_whitelist(sender, add, names): #Add names if add == True else Remove names.
if names: if names:
sender_id = uid(sender) sender_id = uid(sender)
if sender_id not in whitelists: if sender_id not in whitelists:
whitelists[sender_id] = [] whitelists[sender_id] = []
for name in names: for name in names:
player = server.getPlayer(name) player = server.getPlayer(name)
if player: if player:
player_id = uid(player) player_id = uid(player)
pname = player.getName() pname = player.getName()
sname = stripcolors(sender.getDisplayName()) sname = stripcolors(sender.getDisplayName())
# add player to whitelist if not already added # add player to whitelist if not already added
if add and player_id not in whitelists[sender_id]: if add and player_id not in whitelists[sender_id]:
if sender != player: if sender != player:
whitelists[sender_id].append(player_id) whitelists[sender_id].append(player_id)
forcefield_header(sender, "&bAdded &f%s &bto your forcefield whitelist." % pname) forcefield_header(sender, "&bAdded &f%s &bto your forcefield whitelist." % pname)
forcefield_header(player, "&f%s &badded you to his forcefield whitelist." % sname) forcefield_header(player, "&f%s &badded you to his forcefield whitelist." % sname)
else: else:
forcefield_header(sender, "&cYou can't whitelist yourself.") forcefield_header(sender, "&cYou can't whitelist yourself.")
# remove player from whitelist if whitelisted # remove player from whitelist if whitelisted
elif not add and player_id in whitelists[sender_id]: elif not add and player_id in whitelists[sender_id]:
whitelists[sender_id].remove(player_id) whitelists[sender_id].remove(player_id)
forcefield_header(sender, "&cRemoved &f%s &cfrom your forcefield whitelist." % pname) forcefield_header(sender, "&cRemoved &f%s &cfrom your forcefield whitelist." % pname)
forcefield_header(player, "&f%s &cremoved you from his forcefield whitelist." % sname) forcefield_header(player, "&f%s &cremoved you from his forcefield whitelist." % sname)
# player was already / not added to whitelist # player was already / not added to whitelist
else: else:
var = "already" if add == True else "not" var = "already" if add == True else "not"
forcefield_header(sender, "&f%s &cwas %s in your forcefield whitelist!" % (pname, var)) forcefield_header(sender, "&f%s &cwas %s in your forcefield whitelist!" % (pname, var))
else: else:
forcefield_header(sender, "&cplayer &f%s &cwas not found (must be online)." % name) forcefield_header(sender, "&cplayer &f%s &cwas not found (must be online)." % name)
else: else:
forcefield_header(sender, "&cGive space-separated playernames.") forcefield_header(sender, "&cGive space-separated playernames.")
def whitelist_list(player): def whitelist_list(player):
try: player_id = uid(player)
player_id = uid(player) count = 0
count = 0 forcefield_header(player, "&bForcefield whitelist:")
forcefield_header(player, "&bForcefield whitelist:") for user_id in whitelists.get(player_id, []):
for user_id in whitelists.get(player_id, []): count += 1
count += 1 pname = retrieve_player(user_id).getName()
pname = retrieve_player(user_id).getName() msg(player, "&b %s. &f%s" % (count, pname))
msg(player, "&b %s. &f%s" % (count, pname)) if count == 0:
if count == 0: msg(player, "&c Your whitelist has no entries.")
msg(player, "&c Your whitelist has no entries.")
except:
warn("Unable to finish whitelist_list process")
def whitelist_clear(player): def whitelist_clear(player):
player_id = uid(player) player_id = uid(player)
if whitelists.get(player_id): if whitelists.get(player_id):
whitelists.pop(player_id) whitelists.pop(player_id)
forcefield_header(player, "&bForcefield whitelist cleared.") forcefield_header(player, "&bForcefield whitelist cleared.")
else: else:
forcefield_header(player, "&cYou had no players whitelisted.") forcefield_header(player, "&cYou had no players whitelisted.")
def forcefield_help(player): def forcefield_help(player):
msg(player, " ") msg(player, " ")
forcefield_header(player, "&b&l/Forcefield help: Your forcefield is %s" % ("&2&lON" if uid(player) in ff_users else "&c&lOFF")) forcefield_header(player, "&b&l/Forcefield help: Your forcefield is %s" % ("&2&lON" if uid(player) in ff_users else "&c&lOFF"))
msg(player, "&b You can use the forcefield to keep players on distance.") msg(player, "&b You can use the forcefield to keep players on distance.")
msg(player, "&b Commands:") msg(player, "&b Commands:")
msg(player, "&b 1. &6/ff &ohelp &b aliases: &6?") msg(player, "&b 1. &6/ff &ohelp &b aliases: &6?")
msg(player, "&b 2. &6/ff &o(on off)") msg(player, "&b 2. &6/ff &o(on off)")
msg(player, "&b 3. &6/ff &owhitelist (list) &b aliases: &6wlist, wl") msg(player, "&b 3. &6/ff &owhitelist (list) &b aliases: &6wlist, wl")
msg(player, "&b 4. &6/ff wl &oclear") msg(player, "&b 4. &6/ff wl &oclear")
msg(player, "&b 5. &6/ff wl &oadd <players> &b aliases: &6+") msg(player, "&b 5. &6/ff wl &oadd <players> &b aliases: &6+")
msg(player, "&b 6. &6/ff wl &oremove <players> &b aliases: &6delete, rem, del, -") msg(player, "&b 6. &6/ff wl &oremove <players> &b aliases: &6delete, rem, del, -")
msg(player, " ") msg(player, " ")
def forcefield_toggle(player, arg): # arg is a list with max 1 string def forcefield_toggle(player, arg): # arg is a list with max 1 string
player_id = uid(player) player_id = uid(player)
enabled = player_id in ff_users enabled = player_id in ff_users
argoff = arg[0].upper() == "OFF" if arg else False argoff = arg[0].upper() == "OFF" if arg else False
if enabled and (not arg or argoff): # 3 possibilities for arg: [], ["OFF"], ["ON"]. This is the most efficient way. (Case insensitive) if enabled and (not arg or argoff): # 3 possibilities for arg: [], ["OFF"], ["ON"]. This is the most efficient way. (Case insensitive)
ff_users.remove(player_id) ff_users.remove(player_id)
forcefield_header(player, "&bForcefield toggle: &c&lOFF") forcefield_header(player, "&bForcefield toggle: &c&lOFF")
elif not enabled and not argoff: elif not enabled and not argoff:
ff_users.append(player_id) ff_users.append(player_id)
forcefield_header(player, "&bForcefield toggle: &2&lON") forcefield_header(player, "&bForcefield toggle: &2&lON")
else: else:
forcefield_header(player, "&cYour forcefield is already %s!" % arg[0].lower()) forcefield_header(player, "&cYour forcefield is already %s!" % arg[0].lower())
def forcefield_header(player, message): def forcefield_header(player, message):
msg(player, "%s %s" % (ff_prefix, message)) msg(player, "%s %s" % (ff_prefix, message))
#--------------------------------------------------------------------------------------------------------# #--------------------------------------------------------------------------------------------------------#
@@ -149,41 +145,41 @@ def forcefield_header(player, message):
@hook.event("player.PlayerMoveEvent") @hook.event("player.PlayerMoveEvent")
def on_move(event): def on_move(event):
if ff_users: if ff_users:
player = event.getPlayer() player = event.getPlayer()
if is_creative(player): if is_creative(player):
player_id = uid(player) player_id = uid(player)
# moving player has forcefield, nearby player should be moved away # moving player has forcefield, nearby player should be moved away
if player_id in ff_users: if player_id in ff_users:
for entity in player.getNearbyEntities(fd, fd, fd): for entity in player.getNearbyEntities(fd, fd, fd):
whitelisted = (uid(entity) in whitelists.get(player_id, [])) whitelisted = (uid(entity) in whitelists.get(player_id, []))
if is_player(entity) and not entity.hasPermission(pass_perm) and not whitelisted: if is_player(entity) and not entity.hasPermission(pass_perm) and not whitelisted:
move_away(player, entity) move_away(player, entity)
# nearby player has forcefield, moving player should be moved away # nearby player has forcefield, moving player should be moved away
if not player.hasPermission(pass_perm): if not player.hasPermission(pass_perm):
for entity in player.getNearbyEntities(fd, fd, fd): for entity in player.getNearbyEntities(fd, fd, fd):
entity_id = uid(entity) entity_id = uid(entity)
ff_enabled = (entity_id in ff_users) ff_enabled = (entity_id in ff_users)
whitelisted = (player_id in whitelists.get(entity_id, [])) whitelisted = (player_id in whitelists.get(entity_id, []))
if is_player(entity) and is_creative(entity) and ff_enabled and not whitelisted: if is_player(entity) and is_creative(entity) and ff_enabled and not whitelisted:
move_away(entity, player) move_away(entity, player)
def move_away(player, entity): def move_away(player, entity):
# Pushes entity away from player # Pushes entity away from player
player_loc = player.getLocation() player_loc = player.getLocation()
entity_loc = entity.getLocation() entity_loc = entity.getLocation()
dx = entity_loc.getX() - player_loc.getX() dx = entity_loc.getX() - player_loc.getX()
vx = sin(Xv * dx) vx = sin(Xv * dx)
dy = entity_loc.getY() - player_loc.getY() dy = entity_loc.getY() - player_loc.getY()
vy = sin(Xv * dy) vy = sin(Xv * dy)
dz = entity_loc.getZ() - player_loc.getZ() dz = entity_loc.getZ() - player_loc.getZ()
vz = sin(Xv * dz) vz = sin(Xv * dz)
entity.setVelocity(Vector(vx , vy, vz)) entity.setVelocity(Vector(vx , vy, vz))
#--------------------------------------------------------------------------------------------------------# #--------------------------------------------------------------------------------------------------------#
@@ -191,7 +187,7 @@ def move_away(player, entity):
@hook.event("player.PlayerQuitEvent") @hook.event("player.PlayerQuitEvent")
def on_quit(event): def on_quit(event):
player = event.getPlayer() player = event.getPlayer()
player_id = uid(player) player_id = uid(player)
if player_id in ff_users: if player_id in ff_users:
ff_users.remove(player_id) ff_users.remove(player_id)
+115 -117
View File
@@ -1,4 +1,3 @@
import thread
from helpers import * from helpers import *
friends = open_json_file("friends", {}) # {Player_UUID:[List_of_friend_uuids]} friends = open_json_file("friends", {}) # {Player_UUID:[List_of_friend_uuids]}
@@ -8,153 +7,152 @@ friend_join_sound = "random.orb"
@hook.event("player.PlayerJoinEvent", "high") # creates sound and sends a bold message on friend join @hook.event("player.PlayerJoinEvent", "high") # creates sound and sends a bold message on friend join
def fjm(event): # friend join message def fjm(event): # friend join message
player = event.getPlayer() player = event.getPlayer()
player_id = uid(player) player_id = uid(player)
for onlineplayer in list(server.getOnlinePlayers()): for onlineplayer in list(server.getOnlinePlayers()):
if player_id in friends.get(uid(onlineplayer), []): if player_id in friends.get(uid(onlineplayer), []):
msg(onlineplayer, "&a&l%s &ajoined!" % player.getName()) msg(onlineplayer, "&a&l%s &ajoined!" % player.getName())
onlineplayer.playSound(onlineplayer.getLocation(), friend_join_sound, 1, 0) onlineplayer.playSound(onlineplayer.getLocation(), friend_join_sound, 1, 0)
def save_friends(): # saves to friends file def save_friends(): # saves to friends file
save_json_file("friends", friends) save_json_file("friends", friends)
def friendmessage(player, message): # sends a message with a prefix def friendmessage(player, message): # sends a message with a prefix
msg(player, "&7[&aFriends&7] " + message) msg(player, "&7[&aFriends&7] " + message)
def ls(sender): def ls(sender):
try: sender_friends = friends.get(uid(sender), False)
sender_friends = friends.get(uid(sender), False) if sender_friends:
if sender_friends: friends_string = ""
friends_string = "" for uuid in sender_friends:
for uuid in sender_friends: friends_string += (retrieve_player(uuid).getName() + ", ")
friends_string += (retrieve_player(uuid).getName() + ", ") friendmessage(sender, "&aYour friends list: " + friends_string[:len(friends_string)-2])
friendmessage(sender, "&aYour friends list: " + friends_string[:len(friends_string)-2]) else:
else: friendmessage(sender, "&cYour friends list is empty")
friendmessage(sender, "&cYour friends list is empty")
except:
warn("Unable to finish friends' ls process")
def clear(sender): def clear(sender):
sender_id = uid(sender) sender_id = uid(sender)
if friends.get(sender_id, False): if friends.get(sender_id, False):
friends.pop(sender_id) for uuid in friends[sender_id]:
friendmessage(sender, "&aFriends list cleared") friendmessage(retrieve_player(uuid), "&c&o%s &cremoved you from their friends list" % stripcolors(sender.getDisplayName()))
save_friends() friends.pop(sender_id)
else: friendmessage(sender, "&aFriends list cleared")
friendmessage(sender, "&cYour friends list is already empty") save_friends()
else:
friendmessage(sender, "&cYour friends list is already empty")
def add(sender, names): def add(sender, names):
sender_id = uid(sender) sender_id = uid(sender)
added = [] added = []
notfound = [] notfound = []
friendalready = [] friendalready = []
if not sender_id in friends: if not sender_id in friends:
friends[sender_id] = [] friends[sender_id] = []
for name in names: for name in names:
player = server.getPlayer(name) player = server.getPlayer(name)
if player: if player:
player_id = uid(player) player_id = uid(player)
not_yourself = player != sender not_yourself = player != sender
if not player_id in friends[sender_id]: if not player_id in friends[sender_id]:
if not_yourself: if not_yourself:
friends[sender_id].append(player_id) friends[sender_id].append(player_id)
added.append(player.getName()) added.append(player.getName())
friendmessage(player.getPlayer(), "&a&o%s &aadded you to their friends list" % stripcolors(sender.getDisplayName())) friendmessage(player.getPlayer(), "&a&o%s &aadded you to their friends list" % stripcolors(sender.getDisplayName()))
else: else:
friendalready.append(player.getName()) friendalready.append(player.getName())
else: else:
notfound.append(name) notfound.append(name)
save_friends() save_friends()
if added: if added:
friendmessage(sender, "&a&o%s&a added." % ", ".join(added)) friendmessage(sender, "&a&o%s&a added." % ", ".join(added))
if notfound: if notfound:
friendmessage(sender, "&c&o%s&c not found. (must be online)" % ", ".join(notfound)) friendmessage(sender, "&c&o%s&c not found. (must be online)" % ", ".join(notfound))
if friendalready: if friendalready:
friendmessage(sender, "&c&o%s&c is/are already your friend." % ", ".join(friendalready)) friendmessage(sender, "&c&o%s&c is/are already your friend." % ", ".join(friendalready))
if not not_yourself: if not not_yourself:
friendmessage(sender, "&cYou can't add yourself to your friends list.") friendmessage(sender, "&cYou can't add yourself to your friends list.")
def rem(sender, names): def rem(sender, names):
sender_id = uid(sender) sender_id = uid(sender)
removed = [] removed = []
notfound = [] notfound = []
notafriend = [] notafriend = []
for name in names: for name in names:
player = server.Player(name) player = server.Player(name)
if player: if player:
player_id = uid(player) player_id = uid(player)
if player_id in friends.get(sender_id, []): if player_id in friends.get(sender_id, []):
friends[sender_id].remove(player_id) friends[sender_id].remove(player_id)
removed.append(player.getName()) removed.append(player.getName())
friendmessage(player.getPlayer(), "&c&o%s &cremoved you from their friends list" % stripcolors(sender.getDisplayName())) friendmessage(player.getPlayer(), "&c&o%s &cremoved you from their friends list" % stripcolors(sender.getDisplayName()))
else: else:
notafriend.append(player.getName()) notafriend.append(player.getName())
else: else:
notfound.append(name) notfound.append(name)
save_friends() save_friends()
if removed: if removed:
friendmessage(sender, "&a&o%s&a removed." % ", ".join(removed)) friendmessage(sender, "&a&o%s&a removed." % ", ".join(removed))
if notfound: if notfound:
friendmessage(sender, "&c&o%s&c not found. (must be online)" % ", ".join(notfound)) friendmessage(sender, "&c&o%s&c not found. (must be online)" % ", ".join(notfound))
if notafriend: if notafriend:
friendmessage(sender, "&c&o%s&c is/are not in your friends list." % ", ".join(notafriend)) friendmessage(sender, "&c&o%s&c is/are not in your friends list." % ", ".join(notafriend))
def fhelp(sender): def fhelp(sender):
friendmessage(sender, "&a&l/friends help") friendmessage(sender, "&a&l/friends help")
msg(sender, "&a1. /friends &oadd <names...> &6aliases: &o+") msg(sender, "&a1. /friends &oadd <names...> &6aliases: &o+")
msg(sender, "&a2. /friends &orem <names...> &6aliases: &oremove, delete, del, -") msg(sender, "&a2. /friends &orem <names...> &6aliases: &oremove, delete, del, -")
msg(sender, "&a3. /friends &oclear &6aliases: &o/") msg(sender, "&a3. /friends &oclear &6aliases: &o/")
msg(sender, "&a4. /friends &olist &6aliases: &olst, *") msg(sender, "&a4. /friends &olist &6aliases: &olst, *")
msg(sender, "&a5. /friends &ohelp &6aliases: &o?") msg(sender, "&a5. /friends &ohelp &6aliases: &o?")
@hook.command("friends") @hook.command("friends")
def on_friend_command(sender, command, label, args): def on_friend_command(sender, args):
if not is_player(sender): if not is_player(sender):
friendmessage(sender, "&c&lYou can't have friends!") friendmessage(sender, "&c&lYou can't have friends!")
return True
cmd = args[0] if args else None
fargs = args[1:]
# /friends list
if cmd in ["list", "lst", "*"]:
thread.start_new_thread(ls, (sender,))
# /friends clear
elif cmd in ["clear", "/"]:
clear(sender)
# /friends add <names>
elif cmd in ["add", "+"]:
if fargs:
add(sender, fargs)
else:
fhelp(sender)
# /friends remove <names>
elif cmd in ["remove", "rem", "delete", "del", "-"]:
if fargs:
rem(sender, fargs)
else:
fhelp(sender)
else:
fhelp(sender)
return True return True
cmd = args[0] if args else None
fargs = args[1:]
# /friends list
if cmd in ["list", "lst", "*"]:
ls(sender)
# /friends clear
elif cmd in ["clear", "/"]:
clear(sender)
# /friends add <names>
elif cmd in ["add", "+"]:
if fargs:
add(sender, fargs)
else:
fhelp(sender)
# /friends remove <names>
elif cmd in ["remove", "rem", "delete", "del", "-"]:
if fargs:
rem(sender, fargs)
else:
fhelp(sender)
else:
fhelp(sender)
return True
Executable → Regular
+144 -241
View File
@@ -6,311 +6,214 @@ import org.bukkit as bukkit
import org.bukkit.Location as Location import org.bukkit.Location as Location
import org.bukkit.entity.Player as Player import org.bukkit.entity.Player as Player
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause as TeleportCause import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause as TeleportCause
import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
import org.bukkit.block as bblock import org.bukkit.block as bblock
import org.bukkit.event.entity as entity
import org.bukkit.command.ConsoleCommandSender
from org.bukkit.entity import *
from player import get_py_player
from player import py_players
#Imports for async query
from secrets import *
import mysqlhack
from com.ziclix.python.sql import zxJDBC
import threading
from traceback import format_exc as trace
helpers_version = "2.0.0"
shared = {} # this dict can be used to share stuff across modules shared = {} # this dict can be used to share stuff across modules
server = bukkit.Bukkit.getServer() server = bukkit.Bukkit.getServer()
def info(text): def info(text):
""" server.getLogger().info("[RedstonerUtils] %s" % text)
Log info to console
"""
server.getLogger().info("[RedstonerUtils] %s" % text)
def warn(text): def warn(text):
""" server.getLogger().warning("[RedstonerUtils] %s" % text)
Log warning to console
"""
server.getLogger().warning("[RedstonerUtils] %s" % text)
def error(text): def error(text):
""" server.getLogger().severe("[RedstonerUtils] %s" % text)
Log error to console
"""
server.getLogger().severe("[RedstonerUtils] %s" % text)
def fine(text):
"""
Log anything to the logs alone, not the console
"""
server.getLogger().fine(text)
def msg(player, text, usecolor = True, basecolor = None): def msg(player, text, usecolor = True, basecolor = None):
""" """
send a message to player send a message to player
the player may be None or offline, which this method just ignores the player may be None or offline, which this method just ignores
unless usecolor is False, &-codes are translated to real color codes unless usecolor is False, &-codes are translated to real color codes
for that case, basecolor can be useful. basecolor accepts a single character as color code for that case, basecolor can be useful. basecolor accepts a single character as color code
""" """
if player and (player == server.getConsoleSender() or player.isOnline()): # getPlayer() returns None when offline if player and (player == server.getConsoleSender() or player.getPlayer()): # getPlayer() returns None when offline
if basecolor: if basecolor:
if usecolor: if usecolor:
text = colorify(text)
player.sendMessage(colorify("&%s" % basecolor) + text)
else:
player.sendMessage(colorify(text) if usecolor else text)
def broadcast(perm, text, usecolor = True):
"""
better than bukkit's broadcast.
bukkit only works with permissibles that are subscribed to perm
"""
if usecolor:
text = colorify(text) text = colorify(text)
for recipient in list(server.getOnlinePlayers()) + [server.getConsoleSender()]: player.sendMessage(colorify("&%s" % basecolor) + text)
if not perm or recipient.hasPermission(perm): else:
msg(recipient, text, usecolor = False) player.sendMessage(colorify(text) if usecolor else text)
def broadcast(perm, text):
"""
better than bukkit's broadcast.
bukkit only works with permissibles that are subscribed to perm
"""
text = colorify(text)
for recipient in list(server.getOnlinePlayers()) + [server.getConsoleSender()]:
if not perm or recipient.hasPermission(perm):
msg(recipient, text)
def colorify(text): def colorify(text):
""" """
replace &-codes with real color codes replace &-codes with real color codes
""" """
return sub("&(?=[?\\da-fk-or])", u"\u00A7", "%s" % text) return sub("&(?=[?\\da-fk-or])", u"\u00A7", "%s" % text)
def stripcolors(text): def stripcolors(text):
""" """
strips all (real) color codes from text strips all (real) color codes from text
""" """
return sub(u"\u00A7[\\da-fk-or]", "", "%s" % text) return sub(u"\u00A7[\\da-fk-or]", "", "%s" % text)
def safetp(player, world, x, y, z, yaw = 0, pitch = 0): def safetp(player, world, x, y, z, yaw = 0, pitch = 0):
""" """
teleports the player to the given Location teleports the player to the given Location
if the player would spawn inside blocks, the location is escalated until the location is safe if the player would spawn inside blocks, the location is escalated until the location is safe
""" """
tpblock = Location(world, x, y, z).getBlock() tpblock = Location(world, x, y, z).getBlock()
if (tpblock.isEmpty() and tpblock.getRelative(bblock.BlockFace.UP).isEmpty()) or y > 255: if (tpblock.isEmpty() and tpblock.getRelative(bblock.BlockFace.UP).isEmpty()) or y > 255:
player.teleport(Location(world, x+0.5, y, z+0.5, yaw, pitch), TeleportCause.COMMAND) player.teleport(Location(world, x+0.5, y, z+0.5, yaw, pitch), TeleportCause.COMMAND)
else: else:
safetp(player, world, x, y+1, z, yaw, pitch) safetp(player, world, x, y+1, z, yaw, pitch)
def plugin_header(recipient = None, name="Redstoner Utils"): def plugin_header(recipient = None, name="Redstoner Utils"):
""" """
sends the recipient a "Plugin Header", in the format of: --=[ PluginName ]=-- sends the recipient a "Plugin Header", in the format of: --=[ PluginName ]=--
""" """
head = "\n&2--=[ %s ]=--" % name head = "\n&2--=[ %s ]=--" % name
msg(recipient, head) msg(recipient, head)
return head return head
def noperm(player): def noperm(player):
""" msg(player, "&cno permission")
Send the default permission failure message to the player
"""
msg(player, "&cno permission")
def runas(player, cmd): def runas(player, cmd):
""" """
run a command as player run a command as player
the cmd should NOT be prefixed with a / the cmd should no be prefixed with a /
""" """
if is_player(player): server.dispatchCommand(player, cmd)
player.chat("/" + cmd)
else:
server.dispatchCommand(player, cmd)
def is_player(obj): def is_player(obj):
""" """
return True when ob is a bukkit Player return True when ob is a bukkit Player
""" """
return (isinstance(obj, Player)) return (isinstance(obj, Player))
def can_build(player, block):
"""
return True if the player can change/build at the location of given block
"""
event = BlockBreakEvent(block, player)
server.getPluginManager().callEvent(event)
return not event.isCancelled()
def checkargs(sender, args, amin, amax): def checkargs(sender, args, amin, amax):
""" """
check if a command has a valid amount of args, otherwise notify the sender check if a command has a valid amount of args, otherwise notify the sender
amin is the minimum amount of args amin is the minimum amount of args
amax is the maximum amount of args amax is the maximum amount of args
if amax is < 0, infinite args will be accepted if amax is < 0, infinite args will be accepted
return True if args has a valid length, False otherwise return True if args has a valid length, False otherwise
""" """
if not (len(args) >= amin and (amax < 0 or len(args) <= amax)): if not (len(args) >= amin and (amax < 0 or len(args) <= amax)):
if amin == amax: if amin == amax:
msg(sender, "&cNeeds " + str(amin) + " arguments!") msg(sender, "&cNeeds " + str(amin) + " arguments!")
return False return False
elif amax < 0: elif amax < 0:
msg(sender, "&cNeeds at least " + str(amin) + " arguments!") msg(sender, "&cNeeds at least " + str(amin) + " arguments!")
return False return False
else: else:
msg(sender, "&cNeeds " + str(amin) + " to " + str(amax) + " arguments!") msg(sender, "&cNeeds " + str(amin) + " to " + str(amax) + " arguments!")
return False return False
return True return True
def warp(player, args, warpname):
if not checkargs(player, args, 0, 1):
return False # You can check if it worked
runas(player, "warp %s" % warpname)
return True
def is_creative(player): def is_creative(player):
""" """
returns True if the player is in Creative mode returns True if the player is in Creative mode
""" """
return str(player.getGameMode()) == "CREATIVE" return str(player.getGameMode()) == "CREATIVE"
def uid(player): def uid(player):
""" """
returns the player's UUID returns the player's UUID
""" """
return str(player.getUniqueId()) return str(player.getUniqueId())
def retrieve_player(uuid_str): def retrieve_player(uuid_str):
""" """
gets an offline player by UUID string gets an offline player by UUID string
the uuid MUST contain dashes the uuid MUST contain dashes
""" """
return server.getOfflinePlayer(juuid(uuid_str)) return server.getOfflinePlayer(juuid(uuid_str))
def known_player(player): def known_player(player):
""" """
to be used on OfflinePlayer (which can be online!) to be used on OfflinePlayer (which can be online!)
returns True if the player has been on the server returns True if the player has been on the server
this is different to HasPlayedBefore(), which will return False on first join this is different to HasPlayedBefore(), which will return False on first join
""" """
return player.hasPlayedBefore() return player.hasPlayedBefore()
"""
Runs a async query, calls target function with fetchall as an argument, it will be an empty list if there is nothing to fetch.
(So make sure your function takes that argument.)
If you want your function to run sync in the case you are doing something spigot wouldn't like to be async use the bukkit scheduler.
Example can be found in loginsecurity.py
"""
def async_query(mysql_database,query,query_args,target,*target_args,**target_kwargs):
def async_query_t(mysql_database,query,query_args,target,target_args,target_kwargs):
db_conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
db_curs = db_conn.cursor()
db_curs.execute(query,query_args)
db_conn.commit()
fetchall = db_curs.fetchall()
db_curs.close()
db_conn.close()
target(fetchall,target_args,target_kwargs)
t = threading.Thread(target=async_query_t,args=(mysql_database,query,query_args,target,target_args,target_kwargs))
t.daemon = True
t.start()
def open_json_file(filename, default = None): def open_json_file(filename, default):
""" """
opens the given json file and returns an object or returns None on error opens the given json file and returns an object or returns None on error
filename is only the name of the file without .json appended. filename is the path + name of the file.
""" """
try: data = None
with open("plugins/redstoner-utils.py.dir/files/%s.json" % filename) as obj: try:
default = json_loads(obj.read()) with open("plugins/redstoner-utils.py.dir/files/%s.json" % filename) as obj:
except Exception, e: data = json_loads(obj.read())
error("Failed to read from %s: %s" % (filename, e)) except Exception, e:
return default error("Failed to read from %s: %s" % (filename, e))
return (default if data is None else data)
def save_json_file(filename, obj): def save_json_file(filename, obj):
""" """
saves the given object as json into filename saves the given object as json into filename
filename is only the name of the file without .json appended. filename is the path + name of the file.
""" """
try: try:
with open("plugins/redstoner-utils.py.dir/files/%s.json" % filename, "w") as f: with open("plugins/redstoner-utils.py.dir/files/%s.json" % filename, "w") as f:
f.write(json_dumps(obj)) f.write(json_dumps(obj))
except Exception, e: except Exception, e:
error("Failed to write to %s: %s" % (filename, e)) error("Failed to write to %s: %s" % (filename, e))
def toggle(player, ls, name = "Toggle", add = None): def toggle(player, ls, add = None, on = "&aToggle now on!", off = "&cToggle now off!", already = "&cToggle was already %s"):
""" """
Toggles presence of a player's UUID in a list Toggle presence of a player's UUID in a list (ls)
If add is given, True explicitely adds it whereas False removes it 'add' controls if a player should be added(True) or removed(False)
""" if 'add' is None, ls will simply be toggled for that player.
pid = uid(player) when 'add' is given, but won't change anything, %s in 'already' is replaced with "ON" or "OFF"
if pid in ls or add == False: """
ls.remove(pid)
msg(player, "&a%s turned off!" % name)
elif add != False:
ls.append(pid)
msg(player, "&a%s turned on!" % name)
def send_JSON_message(playername, message): pid = uid(player)
bukkit.Bukkit.getServer().dispatchCommand(bukkit.Bukkit.getServer().getConsoleSender(), "tellraw " + playername + " " + message) enabled = pid in ls
# Do some checks and remove pid.
if enabled and add == False:
ls.remove(pid)
msg(player, on)
# Allows to check if a String is a valid IPv4 or not. Accepts any string, returns true if the String is a valid IPv4 # Do some checks and append pid.
def is_ip(tocheck): elif not enabled and add == True:
subsets = ["","","",""] ls.append(pid)
i = 0 msg(player, off)
for j in range(0,len(tocheck)):
if not (tocheck[j] in "0123456789."):
return False
elif tocheck[j] == ".":
i += 1
if (i >= 4):
return False
else:
subsets[i] += tocheck[j]
if not (i == 3):
return False
for j in range(0,3):
if not ((int(subsets[j]) >= 0) & (int(subsets[j]) <= 255)):
return False
return True
# Already on/off (optional)
# Allows the use of e.g. numeric permission nodes like "permission.amount.5" and similar. else:
# To get the data fetch the player and the start of the permission node, looking like "permission.amount." msg(player, already % (" ON" if add else " OFF"))
def get_permission_content(player, permnode):
perms = player.getEffectivePermissions()
for perm in perms:
if str(perm.getPermission()).startswith(permnode):
return str(perm.getPermission()).replace(permnode, "")
# Gets an online player from their name
def get_player(name):
for p in bukkit.Bukkit.getServer().getOnlinePlayers():
if p.getName().lower() == name.lower():
return p
return None
def array_to_list(array):
return_list = []
for a in array:
return_list += [a]
return return_list
-114
View File
@@ -1,114 +0,0 @@
# I'M BUSY! Plugin by Curs3d #
##############################
# Concept by CookieManors :D #
# http://bit.ly/1GnNPW8 #
##############################
# This plugin permits users to
# send a command that renders
# them "busy", not letting them
# to get tpa requests or direct
# messages, except from console.
# On restart, all busy data will
# be cleared.
from helpers import *
from basecommands import simplecommand
from traceback import format_exc as trace
busy_players = []
def unclear():
msg(sender, "Umm, what? Sorry, directions unlclear, got head stuck in washing machine")
@hook.command("busy",
aliases = ["focus"],
usage = "/<command> <on|off|status>",
description = "Sets busy mode on, you cannot recieve tpas and MSGs"
)
def on_busy_command(sender, cmd, label, args):
if not is_player(sender):
msg(sender, "Sorry, Console cannot be busy")
return True
if not sender.hasPermission("utils.busy.allowed"):
plugin_header(recipient = sender, name = "I'M BUSY!")
noperm(sender)
return True
if len(args) == 0:
plugin_header(recipient = sender, name = "I'M BUSY!")
msg(sender, "This plugin allows being busy, and when turned on you will not recieve any direct messages or tpa requests.")
msg(sender, "\nCommands:")
msg(sender, "/busy on: turns on busy mode")
msg(sender, "/busy off: turns off busy mode")
msg(sender, "/busy status [player]: shows your or [player]'s current busy status.")
return True
elif len(args) == 1:
if args[0] == "on":
if sender.getName() in busy_players:
plugin_header(recipient = sender, name = "I'M BUSY!")
msg(sender, "You cannot be even more focused than this without being a jedi!")
return True
busy_players.append(sender.getName())
plugin_header(recipient = sender, name = "I'M BUSY!")
broadcast(None, "%s is now SUPER busy! Don't even TRY bothering them, it will not work!" % sender.getName())
return True
elif args[0] == "off":
plugin_header(recipient = sender, name = "I'M BUSY!")
try:
busy_players.remove(sender.getName())
msg(sender, "Master has sent /busy command, %s is freeee!" % sender.getName())
return True
except ValueError:
msg(sender, "You are not busy! You cannot be even less busy! Are you perhaps bored?")
return True
elif args[0] == "status":
plugin_header(recipient = sender, name = "I'M BUSY!")
if sender.getName() in busy_players:
msg(sender, "You are super-duper busy and concentrated right now. Think, think, think!")
return True
else:
msg(sender, "You are completely unable to focus right now.")
return True
else:
plugin_header(recipient = sender, name = "I'M BUSY!")
unclear()
return False
elif len(args) == 2 and args[0] == "status":
plugin_header(recipient = sender, name = "I'M BUSY!")
if args[1] in busy_players:
msg(sender, "Yes, %s is busy. Shhh..." % args[1])
return True
else:
msg(sender, "No, you're good. Feel free to chat with %s!" % args[1])
return True
else:
plugin_header(recipient = sender, name = "I'M BUSY!")
unclear()
return False
@hook.event("player.PlayerCommandPreprocessEvent", "monitor")
def on_cmd_preprocess_event(event):
message = event.getMessage().split(" ")
if message[0] == "/msg" or message[0] == "/w" or message[0] == "/m" or \
message[0] == "/tell" or message[0] == "/tpa" or message[0] == "/tpahere":
if message[1] in busy_players:
plugin_header(recipient = event.getPlayer(), name = "I'M BUSY!")
msg(event.getPlayer(), "We are sorry, but %s is currently busy. Please try again later." % message[1])
event.setCancelled(True)
@hook.event("player.PlayerQuitEvent", "lowest")
def on_player_leave(event):
try:
busy_players.remove(event.getPlayer().getName())
except:
pass
-32
View File
@@ -1,32 +0,0 @@
from helpers import *
from adminchat import *
imout_toggle_list = []
@hook.command("imout")
def on_imout_command(sender, command, label, args):
if not is_player(sender):
msg(sender, "&cThis command can't be run from the console")
return True
if sender.hasPermission("utils.imout"):
name = sender.getName()
symbol = "&a&l+"
if name in imout_toggle_list:
msg(sender, "&eWelcome back! You are no longer hidden")
msg(sender, "&6We disabled /act for you!")
runas(sender, "vanish off")
if name in imout_toggle_list:
imout_toggle_list.remove(name)
if name in ac_toggle_list:
ac_toggle_list.remove(name)
else:
symbol = "&c&l-"
msg(sender, "&eYou just left... Or didn't you?")
imout_toggle_list.append(name)
runas(sender, "vanish on")
if name not in ac_toggle_list:
msg(sender, "&6We enabled /act for you!")
ac_toggle_list.append(name)
broadcast(None, "%s &7%s" % (symbol, name))
return True
-108
View File
@@ -1,108 +0,0 @@
import mysqlhack
import org.bukkit as bukkit
import json
from java.util import UUID as UUID
from helpers import *
from org.bukkit import *
from traceback import format_exc as trace
from iptracker_secrets import *
iptrack_permission = "utils.iptrack"
iptrack_version = "1.1.0"
@hook.event("player.PlayerJoinEvent", "low")
def on_player_join(event):
t = threading.Thread(target=on_player_join_thread, args=(event, ))
t.daemon = True
t.start()
def on_player_join_thread(event):
player = event.getPlayer()
ip = player.getAddress().getHostString()
uuid = uid(player)
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("SELECT ips FROM uuid2ips WHERE uuid = ?", (uuid, ))
results = curs.fetchall()
if len(results) == 0:
ips = []
else:
ips = json.loads(results[0][0])
curs.execute("SELECT uuids FROM ip2uuids WHERE ip = ?", (ip, ))
results = curs.fetchall()
if len(results) == 0:
uuids = []
else:
uuids = json.loads(results[0][0])
new_ip_entry = (len(ips) == 0)
new_uuid_entry = (len(uuids) == 0)
if ip not in ips:
ips.append(ip)
if new_ip_entry:
curs.execute("INSERT INTO uuid2ips VALUES (?,?)", (uuid, json.dumps(ips), ))
else:
curs.execute("UPDATE uuid2ips SET ips = ? WHERE uuid = ?", (json.dumps(ips), uuid, ))
if uuid not in uuids:
uuids.append(uuid)
if new_uuid_entry:
curs.execute("INSERT INTO ip2uuids VALUES (?,?)", (ip, json.dumps(uuids), ))
else:
curs.execute("UPDATE ip2uuids SET uuids = ? WHERE ip = ?", (json.dumps(uuids), ip, ))
conn.commit()
curs.close()
conn.close()
@hook.command("getinfo")
def on_getinfo_command(sender, args):
t = threading.Thread(target=on_getinfo_command_thread, args=(sender, args))
t.daemon = True
t.start()
def on_getinfo_command_thread(sender, args):
if(sender.hasPermission(iptrack_permission)):
if not checkargs(sender, args, 1, 1):
return False
else:
if is_ip(args[0]):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("SELECT uuids FROM ip2uuids WHERE ip = ?", (args[0], ))
results = curs.fetchall()
curs.close()
conn.close()
if len(results) == 0:
msg(sender, "IP " + args[0] + " is not registered in the database, maybe you got a number wrong?")
else:
uuids = json.loads(results[0][0])
msg(sender, "IP " + args[0] + " was seen with " + str(len(uuids)) + " different Accounts:")
for i in range(0, len(uuids)):
p=Bukkit.getOfflinePlayer(UUID.fromString(uuids[i]))
if is_player(sender):
send_JSON_message(sender.getName(), '["",{"text":"' + p.getName() + ' - (uuid: ' + uuids[i] + '","color":"gold","clickEvent":{"action":"run_command","value":"/getinfo ' + p.getName() + '"},"hoverEvent":{"action":"show_text","value":{"text":"","extra":[{"text":"To search for ' + p.getName() + ' in the database, simply click the name!","color":"gold"}]}}}]')
else:
msg(sender,p.getName() + " - (uuid: " + uuids[i] + ")")
else:
target = Bukkit.getOfflinePlayer(args[0])
uuid = target.getUniqueId()
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("SELECT ips FROM uuid2ips WHERE uuid = ?", (uuid.toString(), ))
results = curs.fetchall()
curs.close()
conn.close()
if len(results) == 0:
msg(sender, "Player " + args[0] + " is not registered in the database, maybe you misspelled the name?")
else:
ips = json.loads(results[0][0])
msg(sender, "Player " + args[0] + " was seen with " + str(len(ips)) + " different IPs:")
for i in range(0, len(ips)):
if is_player(sender):
send_JSON_message(sender.getName(), '["",{"text":"' + ips[i] + '","color":"gold","clickEvent":{"action":"run_command","value":"/getinfo ' + ips[i] + '"},"hoverEvent":{"action":"show_text","value":{"text":"","extra":[{"text":"To search for the IP ' + ips[i] + ' in the database, simply click the IP!","color":"gold"}]}}}]')
else:
msg(sender,ips[i])
else:
noperm(sender)
return True
+39 -39
View File
@@ -6,55 +6,55 @@ lagchunks = []
def print_help(sender): def print_help(sender):
msg(sender, " &b/lagchunks <amount> &eList chunks where #entities >= <amount>") msg(sender, " &b/lagchunks <amount> &eList chunks where #entities >= <amount>")
msg(sender, " &b/lagchunks list &eShow list again") msg(sender, " &b/lagchunks list &eShow list again")
msg(sender, " &b/lagchunks tp <num> &eTeleport to chunk <num> from list") msg(sender, " &b/lagchunks tp <num> &eTeleport to chunk <num> from list")
def scan_chunks(amount): def scan_chunks(amount):
global lagchunks global lagchunks
chunks = [] chunks = []
for world in bukkit.Bukkit.getServer().getWorlds(): for world in bukkit.Bukkit.getServer().getWorlds():
for chunk in world.getLoadedChunks(): for chunk in world.getLoadedChunks():
if len(chunk.getEntities()) >= amount: if len(chunk.getEntities()) >= amount:
ents = chunk.getEntities() ents = chunk.getEntities()
# [0]world [1]X [2]Y [3]Z [4]amount # [0]world [1]X [2]Y [3]Z [4]amount
chunks.append([chunk.getWorld(), int(ents[-1].getLocation().getX()), int(ents[0].getLocation().getY()), int(ents[0].getLocation().getZ()), len(ents)]) chunks.append([chunk.getWorld(), int(ents[-1].getLocation().getX()), int(ents[0].getLocation().getY()), int(ents[0].getLocation().getZ()), len(ents)])
chunks.sort(key = lambda entry: entry[4], reverse = True) chunks.sort(key = lambda entry: entry[4], reverse = True)
lagchunks = chunks lagchunks = chunks
def list_chunks(sender): def list_chunks(sender):
for id, chunk in enumerate(lagchunks): for id, chunk in enumerate(lagchunks):
msg(sender, "&b%s&a: (&b%s&a) %s&7, &a%s &7(%s)" % (id, chunk[4], chunk[1], chunk[3], chunk[0].getName())) msg(sender, "&b%s&a: (&b%s&a) %s&7, &a%s &7(%s)" % (id, chunk[4], chunk[1], chunk[3], chunk[0].getName()))
msg(sender, "&2------------------") msg(sender, "&2------------------")
def tp_chunk(sender, id): def tp_chunk(sender, id):
chunk = lagchunks[id] chunk = lagchunks[id]
safetp(sender, chunk[0], chunk[1], chunk[2], chunk[3]) safetp(sender, chunk[0], chunk[1], chunk[2], chunk[3])
msg(sender, "&aTeleported to &b%s&a, &b%s&a in &7%s&a with &b%s&a entities nearby." % (chunk[1], chunk[3], chunk[0].getName(), chunk[4])) msg(sender, "&aTeleported to &b%s&a, &b%s&a in &7%s&a with &b%s&a entities nearby." % (chunk[1], chunk[3], chunk[0].getName(), chunk[4]))
@hook.command("lagchunks") @hook.command("lagchunks")
def on_lagchunks_command(sender, command, label, args): def on_lagchunks_command(sender, args):
if sender.hasPermission("utils.lagchunks"): if sender.hasPermission("utils.lagchunks"):
plugin_header(sender, "Lagchunks") plugin_header(sender, "Lagchunks")
global lagchunks global lagchunks
if len(args) == 1 and args[0].isdigit() and int(args[0]) > 0: if len(args) == 1 and args[0].isdigit() and int(args[0]) > 0:
amount = args[0] amount = args[0]
msg(sender, "&aChunks with at least &b%s &aentities:" % amount, ) msg(sender, "&aChunks with at least &b%s &aentities:" % amount, )
scan_chunks(int(amount)) scan_chunks(int(amount))
list_chunks(sender) list_chunks(sender)
elif len(args) == 1 and args[0].lower() == "list": elif len(args) == 1 and args[0].lower() == "list":
list_chunks(sender) list_chunks(sender)
elif len(args) == 2 and args[0].lower() == "tp" and args[1].isdigit() and int(args[1]) <= len(lagchunks)-1: elif len(args) == 2 and args[0].lower() == "tp" and args[1].isdigit() and int(args[1]) <= len(lagchunks)-1:
if isinstance(sender, Player): if isinstance(sender, Player):
tp_chunk(sender, int(args[1])) tp_chunk(sender, int(args[1]))
else: else:
msg(sender, "&cOnly players can do this!") msg(sender, "&cOnly players can do this!")
else:
print_help(sender)
else: else:
noperm(sender) print_help(sender)
return True else:
noperm(sender)
return True
-275
View File
@@ -1,275 +0,0 @@
from helpers import *
from passlib.hash import pbkdf2_sha256 as crypt
from basecommands import simplecommand
import time
import threading
from login_secrets import * #Don't forget to make login_secrets aswell
import mysqlhack
from com.ziclix.python.sql import zxJDBC
from java.lang import Runnable
wait_time = 30 #seconds
admin_perm = "utils.loginsecurity.admin"
min_pass_length = 8
blocked_events = ["block.BlockBreakEvent", "block.BlockPlaceEvent", "player.PlayerMoveEvent","player.AsyncPlayerChatEvent"]
def matches(password,user):
thread = threading.Thread(target=matches_thread, args = (password,user))
thread.start()
def matches_thread(password, user):
hashed = get_pass(uid(user))
py_player = get_py_player(user)
if crypt.verify(password, hashed):
if py_player.logging_in:
py_player.logging_in = False
msg(user, "&aLogged in successfully!")
else:
if py_player.logging_in:
msg(user, "&cInvalid password!")
@simplecommand("cgpass",
usage = "<password> <new password>",
description = "Changes your password",
senderLimit = 0,
helpNoargs = True)
def change_pass_command(sender, command, label, args):
py_player = get_py_player(sender)
if py_player.logging_in:
return "&cYou are not logged in"
if not len(args) == 2:
return "&cInvalid arguments"
password = args[0]
new_password = args[1]
uuid = uid(sender)
if is_registered(uuid):
change_pass(uuid, crypt.encrypt(new_password, rounds=200000, salt_size=16))
return "&aPassword changed"
return "&cYou are not registered"
@simplecommand("login",
usage = "<password>",
description = "Logs you in if <password> matches your password.",
senderLimit = 0,
helpNoargs = True)
def login_command(sender, command, label, args):
py_player = get_py_player(sender)
if not py_player.logging_in:
msg(sender,"&cAlready logged in!")
password = args[0]
matches(password, sender)
@simplecommand("register",
usage = "<password>",
description = "Registers you with <password>. Next time you join, log in with /login",
senderLimit = 0,
helpNoargs = True)
def register_command(sender, command, label, args):
py_player = get_py_player(sender)
if len(args) > 1:
return "&cPassword can only be one word!"
uuid = uid(sender)
if is_registered(uuid):
return "&cYou are already registered!"
password = args[0]
if len(password) < min_pass_length:
return "&cThe password has to be made up of at least %s characters!" % min_pass_length
create_pass(uuid, password)
return "&cPassword set. Use /login <password> upon join."
@simplecommand("rmpass",
description = "Removes your password if the password matches",
senderLimit = 0,
amax = 0,
helpNoargs = False)
def rmpass_command(sender, command, label, args):
py_player = get_py_player(sender)
if py_player.logging_in:
return "&cYou are not logged in"
if not is_registered(uid(sender)):
return "&cYou are not registered!"
if py_player.logging_in == False:
delete_pass(uid(sender))
return "&aPassword removed successfully. You will not be prompted anymore."
return "&cFailed to remove password, please contact a staff member"
@simplecommand("rmotherpass",
aliases = ["lacrmpass"],
usage = "<user>",
senderLimit = -1,
description = "Removes password of <user> and sends them a notification",
helpNoargs = True)
def rmotherpass_command(sender, command, label, args):
py_player = get_py_player(sender)
if py_player.logging_in:
return "&cYou are not logged in"
if not sender.hasPermission(admin_perm):
noperm(sender)
return
user = server.getOfflinePlayer(args[0])
if is_registered(uid(user)):
delete_pass(uid(user))
runas(server.getConsoleSender(), colorify("mail send %s &cYour password was reset by a staff member. Use &6/register&c to set a new one." % user.getName()))
return "&aPassword of %s reset successfully" % user.getName()
return "&cThat player could not be found (or is not registered)"
def change_pass(uuid, pw):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("UPDATE secret SET pass = ? WHERE uuid = ?", (pw,uuid,))
conn.commit()
curs.close()
conn.close()
def get_pass(uuid):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("SELECT pass FROM secret WHERE uuid = ?", (uuid,))
results = curs.fetchall()
curs.close()
conn.close()
return results[0][0]
def create_pass(uuid,pw):
thread = threading.Thread(target=create_pass_thread, args=(uuid,pw))
thread.start()
def create_pass_thread(uuid, pw):
pw = crypt.encrypt(pw, rounds=200000, salt_size=16)
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("INSERT INTO secret VALUES (?,?)", (uuid,pw,))
conn.commit()
curs.close()
conn.close()
def is_registered(uuid):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("SELECT EXISTS(SELECT * FROM secret WHERE uuid = ?)", (uuid,))
results = curs.fetchall()
curs.close()
conn.close()
if results[0][0] == 1:
return True
return False
def delete_pass(uuid):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute("DELETE FROM secret WHERE uuid = ?", (uuid,))
conn.commit()
curs.close()
conn.close()
@hook.event("player.PlayerJoinEvent", "highest")
def on_join(event):
user = event.getPlayer()
py_player = get_py_player(event.getPlayer())
if is_registered(uid(user)):
msg(event.getPlayer(), "&4You will be disconnected after 60 seconds if you don't &alogin")
msg(user, "&cUse /login <password>")
py_player.logging_in = True
py_player.login_time = time.time()
return
elif user.hasPermission(admin_perm):
pass #Do what? force them to make a password, lots of code, maybe just message us on slack?
#This shouldn't be needed anymore as py_player gets removed anyway.
"""
@hook.event("player.PlayerQuitEvent", "high")
def on_quit(event):
if event.getPlayer().getName() in logging_in:
del logging_in[event.getPlayer().getName()]
"""
##Threading start
class kick_class(Runnable):
def __init__(self, player):
self.player = player
def run(self):
if self.player.isOnline():
self.player.kickPlayer(colorify("&aLogin timed out"))
def kick_thread():
while True:
time.sleep(1)
now = time.time()
for py_player in py_players:
if py_player.logging_in:
if now - py_player.login_time > wait_time:
player = py_player.player
kick = kick_class(player)
server.getScheduler().runTask(server.getPluginManager().getPlugin("RedstonerUtils"), kick)
"""if name in logging_in:
del logging_in[name]
break
"""
thread = threading.Thread(target = kick_thread)
thread.daemon = True
thread.start()
##Threading end
for blocked_event in blocked_events:
@hook.event(blocked_event, "high")
def on_blocked_event(event):
user = get_py_player(event.getPlayer())
if user.logging_in:
event.setCancelled(True)
@hook.event("player.PlayerCommandPreprocessEvent","normal")
def pre_command_proccess(event):
player = get_py_player(event.getPlayer())
if player.logging_in:
args = event.getMessage().split(" ")
if not args[0].lower() == "/login":
msg(player.player, "&4You need to login before you do that!")
event.setCancelled(True)
+26 -85
View File
@@ -9,107 +9,48 @@ from traceback import format_exc as print_traceback
sys.path += ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/pymodules/python2.7', '/usr/lib/pyshared/python2.7'] sys.path += ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/pymodules/python2.7', '/usr/lib/pyshared/python2.7']
try: try:
# Library that adds a bunch of re-usable methods which are used in nearly all other modules from helpers import *
from helpers import *
except: except:
print("[RedstonerUtils] ERROR: Failed to import helpers:") print("[RedstonerUtils] ERROR: Failed to import helpers:")
print(print_traceback()) print(print_traceback())
@hook.enable @hook.enable
def on_enable(): def on_enable():
info("RedstonerUtils enabled!") info("RedstonerUtils enabled!")
@hook.disable @hook.disable
def on_disable(): def on_disable():
shared["modules"]["reports"].stop_reporting() shared["modules"]["reports"].stop_reporting()
info("RedstonerUtils disabled!") info("RedstonerUtils disabled!")
info("Loading RedstonerUtils...") info("Loading RedstonerUtils...")
# Import all modules, in this order # Import all modules, in this order
shared["load_modules"] = [ shared["load_modules"] = [
# Collection of tiny utilities "misc",
"misc", "adminchat",
# Adds chat for staff using /ac <text or ,<text> "lagchunks",
"adminchat", "reports",
# Adds /badge, allows to give players achievements "chatgroups",
"badges", "webtoken",
# Adds a few block placement corrections/mods "saylol",
"blockplacemods", "skullclick",
# Adds /calc, toggles automatic solving of Math expressions in chat "mentio",
"calc", "cycle",
# Adds aliasing of chat words "motd",
#"chatalias", "abot",
# Plugin to locate laggy chunks. /lc <n> lists chunks with more than n entities "forcefield",
"lagchunks", "friends"
# Adds /report and /rp, Stores reports with time and location
"reports",
# Adds group-chat with /chatgroup and /cgt to toggle normal chat into group mode
"chatgroups",
# Adds /token, reads and writes from the database to generate pronouncable (and thus memorable) registration-tokens for the website
"webtoken",
# Adds /lol, broadcasts random funyy messages. A bit like the splash text in the menu
"saylol",
# Adds /signalstrength, lets you request a signal strength and an amount of items will be inserted into target container to meet that strength.
"signalstrength",
# Shows the owner of a skull when right-clicked
"skullclick",
# Adds /listen, highlights chat and plays a sound when your name was mentioned
"mentio",
# Adds /cycler, swaps the hotbar with inventory when player changes slot from right->left or left->right
"cycle",
# Adds /getmotd & /setmotd to update the motd on the fly (no reboot)
"motd",
# AnswerBot. Hides stupid questions from chat and tells the sender about /faq or the like
"abot",
# Adds '/forcefield', creates forcefield for players who want it.
"forcefield",
# Adds /damnspam, creates timeout for buttons/levers to mitigate button spam.
"damnspam",
# Adds /check, useful to lookup details about a player
"check",
# Adds /an, a command you can use to share thoughts/plans/news
"adminnotes",
# Adds busy status to players
"imbusy",
# Adds /imout, displays fake leave/join messages
"imout",
#adds snowbrawl minigame
"snowbrawl",
# Adds /tm [player] for a messages to be sent to this player via /msg
"pmtoggle",
# Replacement for LoginSecurity
"loginsecurity",
# Centralized Player class
"player",
# Servercontrol extension for telnet access to logs/AC
#"servercontrol",
# Script helper plugin
"scriptutils",
# Per-player notes
"tag",
# vanish toggle module - temporary fix
#"vanishfix",
# obisidian mining punishment plugin
"punishments",
# a simple replacement for the buggy essentials /vanish
"vanish",
# ip-tracking utility - disabled as of instability
#"iptracker",
#server signs for everyone
"serversigns",
# Makes player's names colored, sorts tab list by rank
"nametags"
] ]
shared["modules"] = {} shared["modules"] = {}
for module in shared["load_modules"]: for module in shared["load_modules"]:
try: try:
shared["modules"][module] = __import__(module) shared["modules"][module] = __import__(module)
info("Module %s loaded." % module) info("Module %s loaded." % module)
except: except:
error("Failed to import module %s:" % module) error("Failed to import module %s:" % module)
error(print_traceback()) error(print_traceback())
+103 -109
View File
@@ -4,146 +4,140 @@ from traceback import format_exc as print_traceback
mentions = open_json_file("mentio", {}) # contains a list of keywords for each player (uuid) mentions = open_json_file("mentio", {}) # contains a list of keywords for each player (uuid)
max_amount = 1000 max_amount = 3
arrow = colorify(u"&r&7\u2192&r") arrow = colorify(u"&r&7\u2192&r")
colors_reg = reg_compile(u"\u00A7[\\da-fk-or]") # finds color codes colors_reg = reg_compile(u"\u00A7[\\da-fk-or]") # finds color codes
def saveMentions(): def saveMentions():
save_json_file("mentio", mentions) save_json_file("mentio", mentions)
@hook.event("player.AsyncPlayerChatEvent", "monitor") @hook.event("player.AsyncPlayerChatEvent", "high")
def onChat(event): def onChat(event):
if not event.isCancelled(): if not event.isCancelled():
sender = event.getPlayer() sender = event.getPlayer()
words = event.getMessage().split(" ") words = event.getMessage().split(" ")
recipients = event.getRecipients() # set of <Player>, may be a lazy or unmodifiable collection recipients = event.getRecipients() # set of <Player>, may be a lazy or unmodifiable collection
for recipient in list(recipients): for recipient in list(recipients):
recuid = uid(recipient) recuid = uid(recipient)
if recuid in mentions: if recuid in mentions:
keywords = mentions[uid(recipient)] keywords = mentions[uid(recipient)]
else: else:
# player # player
keywords = [recipient.getName().lower(), stripcolors(recipient.getDisplayName()).lower()] keywords = [recipient.getName().lower(), stripcolors(recipient.getDisplayName()).lower()]
rec_words = words[:] # copy rec_words = words[:] # copy
for index, word in enumerate(rec_words): for index, word in enumerate(rec_words):
isMentioned = False isMentioned = False
for keyword in keywords: for keyword in keywords:
if keyword in word.lower(): # is the keyword mentioned if keyword in word.lower(): # is the keyword mentioned
isMentioned = True isMentioned = True
if isMentioned: if isMentioned:
# join all color codes used upto this word # join all color codes used upto this word
colors = "".join(colors_reg.findall("".join(words[:index+1]))) colors = "".join(colors_reg.findall("".join(words[:index+1])))
# highlight the word containing mention, then apply all previous color codes # highlight the word containing mention, then apply all previous color codes
rec_words[index] = colorify("&r&a&o") + stripcolors(word) + colorify("&r") + colors rec_words[index] = colorify("&r&a&o") + stripcolors(word) + colorify("&r") + colors
# No need to # No need to
break break
# player was mentioned # player was mentioned
if rec_words != words: if rec_words != words:
try: try:
recipients.remove(recipient) # don't send original message recipients.remove(recipient) # don't send original message
except: except:
# list might not be mutable, ignoring. Receiver will get the message twice # list might not be mutable, ignoring. Receiver will get the message twice
pass pass
message = " "+" ".join([sender.getDisplayName(), arrow] + rec_words) message = " ".join([sender.getDisplayName(), arrow] + rec_words)
msg(recipient, message, usecolor = False) msg(recipient, message, usecolor = False)
recipient.playSound(recipient.getLocation(), "mob.chicken.plop", 1, 2) recipient.playSound(recipient.getLocation(), "mob.chicken.plop", 1, 2)
def get_keywords(player): def get_keywords(player):
sender_id = uid(player) sender_id = uid(player)
if sender_id in mentions.keys(): if sender_id in mentions.keys():
keywords = mentions[sender_id] keywords = mentions[sender_id]
else: else:
keywords = [] keywords = []
return keywords return keywords
def add_keyword(sender, args): def add_keyword(sender, args):
keywords = get_keywords(sender) keywords = get_keywords(sender)
new_word = stripcolors(args[1].lower()) new_word = stripcolors(args[1].lower())
if (len(keywords) >= max_amount) and (max_amount >= 0): if len(keywords) >= max_amount:
msg(sender, "&cYou are already listening for %s words! Try &6/mentio del <word>" % max_amount) msg(sender, "&cYou are already listening for %s words! Try &6/mentio del <word>" % max_amount)
return True
if len(new_word) > 20:
msg(sender, "&cThis word is longer than 20 characters. Pick a shorter one!")
return True
if new_word in keywords:
msg(sender, "&cYou are already listening for this word! Try &6/mentio list")
return True
keywords.append(new_word)
if keywords:
mentions[uid(sender)] = keywords
msg(sender, "&aYou are now listening for '&2%s&2'!" % new_word)
saveMentions()
return True return True
if len(new_word) > 20:
msg(sender, "&cThis word is longer than 20 characters. Pick a shorter one!")
return True
if new_word in keywords:
msg(sender, "&cYou are already listening for this word! Try &6/mentio list")
return True
keywords.append(new_word)
if keywords:
mentions[uid(sender)] = keywords
msg(sender, "&aYou are now listening for '&2%s'!" % new_word)
saveMentions()
return True
def del_keyword(sender, args): def del_keyword(sender, args):
keywords = get_keywords(sender) keywords = get_keywords(sender)
del_word = stripcolors(args[1].lower()) del_word = stripcolors(args[1].lower())
if not keywords: if not keywords:
msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>") msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>")
return return
if del_word in keywords: if del_word in keywords:
keywords.remove(del_word) keywords.remove(del_word)
sender_id = uid(sender) sender_id = uid(sender)
if keywords: if keywords:
mentions[sender_id] = keywords mentions[sender_id] = keywords
elif sender_id in mentions: elif sender_id in mentions:
del mentions[sender_id] del mentions[sender_id]
saveMentions() saveMentions()
msg(sender, "&aYou are no longer listening for '&2%s&2'!" % del_word) msg(sender, "&aYou are no longer listening for '&2%s&e'!" % del_word)
else: else:
msg(sender, "&cWe can't remove something that doesn't exist! Try &6/mentio list") msg(sender, "&cWe can't remove something that doesn't exist! Try &6/mentio list")
def show_help(player):
msg(player, "&a/mentio add <word>")
msg(player, "&a/mentio del <word>")
msg(player, "&a/mentio list")
@hook.command("mentio") @hook.command("mentio")
def onListenCommand(sender, command, label, args): def onListenCommand(sender, args):
plugin_header(sender, "Mentio") plugin_header(sender, "Mentio")
argnum = len(args) argnum = len(args)
if argnum: if argnum:
cmd = args[0].lower() cmd = args[0].lower()
# /mentio add <word> # /mentio add <word>
if argnum == 2 and cmd == "add": if argnum == 2 and cmd == "add":
add_keyword(sender, args) add_keyword(sender, args)
# /mentio del <word> # /mentio del <word>
elif argnum == 2 and cmd == "del": elif argnum == 2 and cmd == "del":
del_keyword(sender, args) del_keyword(sender, args)
# /mentio list # /mentio list
elif argnum == 1 and cmd == "list": elif argnum == 1 and cmd == "list":
msg(sender, "&aWords you're listening for:") msg(sender, "&aWords you're listening for:")
keywords = get_keywords(sender) keywords = get_keywords(sender)
for word in keywords: for word in keywords:
msg(sender, "&c- &3%s" % word) msg(sender, "&c- &3%s" % word)
if not keywords: if not keywords:
msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>") msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>")
else: else:
show_help(sender) msg(sender, "&a/mentio add <word>")
else: msg(sender, "&a/mentio del <word>")
show_help(sender) msg(sender, "&a/mentio list")
return True return True
+117 -273
View File
@@ -1,312 +1,156 @@
#pylint: disable = F0401 #pylint: disable = F0401
from helpers import * from helpers import *
from time import time as now from time import time as now
from time import sleep
from sys import exc_info from sys import exc_info
import thread import thread
import org.bukkit.inventory.ItemStack as ItemStack import org.bukkit.inventory.ItemStack as ItemStack
import org.bukkit.Bukkit as Bukkit
from basecommands import simplecommand, Validate
import java.util.Arrays as Arrays
#
# Welcome new players
#
@hook.event("player.PlayerJoinEvent", "monitor") @hook.event("player.PlayerJoinEvent", "monitor")
def on_join(event): def on_join(event):
""" player = event.getPlayer()
Welcome new players
"""
player = event.getPlayer()
# send welcome broadcast # send welcome broadcast
if not player.hasPlayedBefore(): if not player.hasPlayedBefore():
broadcast("utils.greet_new", "\n&a&lPlease welcome &f" + player.getDisplayName() + " &a&lto Redstoner!\n") broadcast("utils.greet_new", "")
broadcast("utils.greet_new", "&a&lPlease welcome &f" + player.getDisplayName() + " &a&lto Redstoner!")
broadcast("utils.greet_new", "")
# clear out some eventual crap before # clear out some eventual crap before
msg(player, " \n \n \n \n \n \n \n \n \n \n \n \n ") msg(player, " \n \n \n \n \n \n \n \n \n \n \n \n ")
msg(player, " &4Welcome to the Redstoner Server!") msg(player, " &4Welcome to the Redstoner Server!")
msg(player, " &6Before you ask us things, take a quick") msg(player, " &6Before you ask us things, take a quick")
msg(player, " &6look at &a&nredstoner.com/info") msg(player, " &6look at the &a&l/FAQ &6command.")
msg(player, " \n&6thank you and happy playing ;)") msg(player, " \n&6thank you and happy playing ;)")
msg(player, " \n \n") msg(player, " \n \n")
# teleport to spawn when spawning inside portal # teleport to spawn when spawning inside portal
loginloc = player.getLocation().getBlock().getType() loginloc = player.getLocation().getBlock().getType()
headloc = player.getEyeLocation().getBlock().getType() headloc = player.getEyeLocation().getBlock().getType()
if "PORTAL" in [str(headloc), str(loginloc)]: if str(loginloc) == "PORTAL" or str(headloc) == "PORTAL":
msg(player, "&4Looks like you spawned in a portal... Let me help you out") msg(player, "&4Looks like you spawned in a portal... Let me help you out")
msg(player, "&6You can use /back if you &nreally&6 want to go back") msg(player, "&6You can use /back if you &nreally&6 want to go back")
player.teleport(player.getWorld().getSpawnLocation()) player.teleport(player.getWorld().getSpawnLocation())
"""
This code fixes /up 0 destroying/replacing blocks in plots that are not yours.
If you use //up, this is caught by plotme and cancelled if you are not allowed to build.
However, if you use //up, WorldEdit does the following on "low" priority:
* Change the command to /up with the same arguments
* Run another event with /up but its cancelled (dunno why it does this)
Keep in mind that, on "lowest" priority, PlotMe might cancel events.
""" #
dup = 0 #Used to store when someone used //up # /sudo - execute command/chat *as* a player/console
#
@hook.event("player.PlayerCommandPreprocessEvent", "lowest")
def cmd_event(event):
global dup
if event.getMessage().split(" ")[0] in ("//up", "/worldedit:/up"):
dup = True
@hook.event("player.PlayerCommandPreprocessEvent", "normal")
def cmd_event2(event):
global dup
args = event.getMessage().split(" ")
if args[0].lower() in ("/up", "/worldedit:up"):
if dup: #If plotme cancelled this, it will not matter. This lets it through but PlotMe doesn't.
dup = False
elif not event.isCancelled():
event.setCancelled(True)
event.getPlayer().chat("//up " + " ".join(args[1:]))
@hook.command("sudo")
def on_sudo_command(sender, args):
""" Disabled while builder can't access Trusted if sender.hasPermission("utils.sudo"):
@hook.event("player.PlayerGameModeChangeEvent", "low") plugin_header(sender, "Sudo")
def on_gamemode(event): if not checkargs(sender, args, 2, -1):
user = event.getPlayer() return True
if str(event.getNewGameMode()) != "SPECTATOR" and user.getWorld().getName() == "Trusted" and not user.hasPermission("mv.bypass.gamemode.Trusted"):
event.setCancelled(True)
"""
@hook.event("player.PlayerBedEnterEvent")
def on_bed_enter(event):
world = event.getPlayer().getWorld()
if world.getName() in ("Survival_1", "TrustedSurvival_1"):
for player in world.getPlayers():
player.setSleepingIgnored(True)
@hook.event("player.PlayerTeleportEvent")
def on_player_teleport(event):
"""
Disable spectator teleportation
"""
player = event.getPlayer()
if not event.isCancelled() and str(event.getCause()) == "SPECTATE" and not player.hasPermission("utils.tp.spectate"):
event.setCancelled(True)
msg(event.getPlayer(), "&cSpectator teleportation is disabled")
@hook.event("block.BlockFromToEvent", "highest")
def on_flow(event):
if event.isCancelled():
return
block = event.getToBlock()
if block.getWorld().getName() == "Creative" and rs_material_broken_by_flow(str(block.getType())):
event.setCancelled(True)
def rs_material_broken_by_flow(material):
if material in ("REDSTONE", "LEVER", "TRIPWIRE"):
return True
parts = material.split("_")
length = len(parts)
return length > 1 and (parts[0] == "DIODE" or parts[1] in ("TORCH", "WIRE", "BUTTON", "HOOK") or (length == 3 and parts[1] == "COMPARATOR"))
@hook.event("player.PlayerInteractEvent")
def on_interact(event):
if (not event.isCancelled()
and str(event.getAction()) == "RIGHT_CLICK_BLOCK"
and str(event.getMaterial()) in ("REDSTONE_COMPARATOR_OFF", "REDSTONE_COMPARATOR_ON")
and not can_build(player, event.getClickedBlock())
):
event.setCancelled(True)
sudo_blacklist = ["pyeval", "script_backup_begin", "script_backup_end", "script_backup_error", "script_backup_database_begin", "script_backup_database_dumps", "script_backup_database_end",
"script_backup_database_error", "script_backup_database_abort", "script_trim", "script_trim_result", "script_spigot_update", "script_disk_filled", "script_restart", "script_restart_abort",
"script_stop", "script_stop_abort", "script_shutdown", "stop", "esudo", "essentials:sudo", "sudo"]
@simplecommand("sudo",
usage = "<player> [cmd..]",
description = "Makes <player> write [cmd..] in chat",
amin = 2,
helpNoargs = True)
def on_sudo_command(sender, command, label, args):
target = args[0] target = args[0]
cmd = " ".join(args[1:])
msg(sender, "&2[SUDO] &rRunning '&e%s&r' as &3%s" % (cmd, target)) cmd = " ".join(args[1:])
is_cmd = cmd[0] == "/" msg(sender, "Running '&e%s&r' as &3%s" % (cmd, target))
is_console = target.lower() in ["server", "console"] if cmd[0] == "/":
first_cmd = (args[1])[1:] if is_cmd else None cmd = cmd[1:]
if first_cmd in sudo_blacklist and (is_player(sender) and uid(sender) not in pythoners): if target.lower() == "server" or target.lower() == "console":
return "&cYou can't sudo this command" runas(server.getConsoleSender(), cmd)
if is_console: elif server.getPlayer(target):
server.dispatchCommand(server.getConsoleSender(), cmd[1:] if is_cmd else cmd) runas(server.getPlayer(target), cmd)
return None else:
target_player = server.getPlayer(target) msg(sender, "&cPlayer %s not found!" % target)
if target_player: else:
target_player.chat(cmd) if target.lower() == "server" or target.lower() == "console":
return None runas(server.getConsoleSender(), "say %s" % cmd)
return "&cPlayer %s not found!" % target elif server.getPlayer(target):
server.getPlayer(target).chat(cmd)
else:
msg(sender, "&cPlayer %s not found!" % target)
else:
noperm(sender)
return True
#
# Clicking redstone_sheep with shears will drop redstone + wool and makes a moo sound
#
@simplecommand("me", last_shear = 0.0
usage = "[message..]",
description = "Sends a message in third person", @hook.event("player.PlayerInteractEntityEvent")
helpNoargs = True) def on_player_entity_interact(event):
def on_me_command(sender, command, label, args): global last_shear
text = colorify("&7- %s &7%s " % (sender.getDisplayName() if isinstance(sender, Player) else "&9CONSOLE", u"\u21E6")) if not event.isCancelled():
broadcast("utils.me", text + " ".join(args), usecolor = sender.hasPermission("essentials.chat.color")) shear_time = now()
return None if last_shear + 0.4 < shear_time:
last_shear = shear_time
sender = event.getPlayer()
entity = event.getRightClicked()
if is_player(entity) and uid(entity) == "ae795aa8-6327-408e-92ab-25c8a59f3ba1" and str(sender.getItemInHand().getType()) == "SHEARS" and is_creative(sender):
for _ in range(5):
entity.getWorld().dropItemNaturally(entity.getLocation(), ItemStack(bukkit.Material.getMaterial("REDSTONE")))
entity.getWorld().dropItemNaturally(entity.getLocation(), ItemStack(bukkit.Material.getMaterial("WOOL")))
sender.playSound(entity.getLocation(), "mob.cow.say", 1, 1)
#
# /pluginversions - print all plugins + versions; useful when updating plugins
#
@hook.command("pluginversions") @hook.command("pluginversions")
def on_pluginversions_command(sender, command, label, args): def on_pluginversions_command(sender, args):
""" plugin_header(sender, "Plugin versions")
/pluginversions plugins = list(server.getPluginManager().getPlugins())
print all plugins + versions; useful when updating plugins plugins.sort(key = lambda pl: pl.getDescription().getName())
""" msg(sender, "&3Listing all " + str(len(plugins)) + " plugins and their version:")
try: for plugin in plugins:
plugin_header(sender, "Plugin versions") msg(sender, "&6" + plugin.getDescription().getName() + "&r: &e" + plugin.getDescription().getVersion())
raw_plugins = server.getPluginManager().getPlugins() # Plugin[] return True
plugins = [raw_plugins[i].getDescription() for i in range(len(raw_plugins))]
info(type(plugins[0]).__name__)
plugins.sort(key = lambda pl: pl.getDescription().getName())
msg(sender, "&3Listing all " + str(len(plugins)) + " plugins and their version:")
for plugin in plugins:
msg(sender, "&6" + pl.getDescription().getName() + "&r: &e" + pl.getDescription().getVersion())
return True
except:
error(trace())
#
# /echo - essentials echo sucks and prints mail alerts sometimes
#
@hook.command("echo") @hook.command("echo")
def on_echo_command(sender, command, label, args): def on_echo_command(sender, args):
""" msg(sender, " ".join(args).replace("\\n", "\n"))
/echo
essentials echo sucks and prints mail alerts sometimes
"""
msg(sender, " ".join(args).replace("\\n", "\n"))
#
# /pyeval - run python ingame
#
# has to be in main.py so we can access the modules
def eval_thread(sender, code): def eval_thread(sender, code):
""" try:
/pyeval result = eval(code)
run python ingame msg(sender, ">>> %s: %s" % (colorify("&3") + type(result).__name__, colorify("&a") + unicode(result) + "\n "), usecolor = False)
""" except:
e = exc_info()[1]
try: try:
result = eval(code) eclass = e.__class__
msg(sender, ">>> %s: %s" % (colorify("&3") + type(result).__name__, colorify("&a") + unicode(result) + "\n "), usecolor = False) except AttributeError:
except: eclass = type(e)
e = exc_info()[1] msg(sender, ">>> %s: %s" % (eclass.__name__, e) + "\n ", False, "c")
try: thread.exit()
eclass = e.__class__
except AttributeError:
eclass = type(e)
msg(sender, ">>> %s: %s" % (eclass.__name__, e) + "\n ", False, "c")
thread.exit()
pythoners = [
"e452e012-2c82-456d-853b-3ac8e6b581f5", # Nemes
"ae795aa8-6327-408e-92ab-25c8a59f3ba1", # jomo
"305ccbd7-0589-403e-a45b-d791dcfdee7d", # PanFritz
"51f2ad3c-6cc8-40ea-aa2b-f25970316921" # Dico
]
@simplecommand("pyeval", @hook.command("pyeval")
usage = "[code..]", def on_pyeval_command(sender, args):
description = "Runs python [code..] and returns the result", if sender.hasPermission("utils.pyeval"):
helpNoargs = True) if not checkargs(sender, args, 1, -1):
def on_pyeval_command(sender, command, label, args): return True
if is_player(sender) and uid(sender) not in pythoners: msg(sender, "%s" % " ".join(args), False, "e")
return noperm(sender)
msg(sender, " ".join(args), False, "e")
thread.start_new_thread(eval_thread, (sender, " ".join(args))) thread.start_new_thread(eval_thread, (sender, " ".join(args)))
return None else:
noperm(sender)
return True
@simplecommand("tempadd",
usage = "<user> <group> [duration]",
description = "Temporarily adds <user> to <group> for \n[duration] minutes. Defaults to 1 week.",
helpNoargs = True,
helpSubcmd = True,
amin = 2,
amax = 3)
def tempadd_command(sender, command, label, args):
if not sender.hasPermission("permissions.manage.membership." + args[1]):
return "&cYou do not have permission to manage that group!"
if len(args) == 3:
if not args[2].isdigit():
return "&cThats not a number!"
duration = int(args[2]) * 60
else:
duration = 604800
if duration <= 0:
return "&cThats too short!"
cmd = "pex user %s group add %s * %s" % (args[0], args[1], duration)
runas(sender, cmd)
m, s = divmod(duration, 60)
h, m = divmod(m, 60)
d, h = divmod(h, 24)
return "&aAdded to group for %dd%dh%dm" % (d, h, m)
@hook.command("modules") @hook.command("modules")
def on_modules_command(sender, command, label, args): def on_modules_command(sender, args):
""" plugin_header(sender, "Modules")
/modules for mod in shared["load_modules"]:
list all modules, unloaded modules in red color = "a" if mod in shared["modules"] else "c"
""" msg(sender, "&" + color + mod)
plugin_header(sender, "Modules")
msg(sender, ", ".join([(("&a" if mod in shared["modules"] else "&c") + mod) for mod in shared["load_modules"]]))
@simplecommand("warn",
usage = "",
description = "Warns everybody on the server that you will cause lag shortly",
amax = 0,
helpSubcmd = True)
def warn_command(sender, command, label, args):
if sender.hasPermission("utils.warn"):
broadcast(None, " &b= &2&lLag incoming! &r-%s" % sender.getDisplayName())
else:
noperm(sender)
@simplecommand("warnp",
usage = "",
description = "Warns everybody on the server that you might cause lag shortly",
amax = 0,
helpSubcmd = True)
def warnp_command(sender, command, label, args):
if sender.hasPermission("utils.warnp"):
broadcast(None, " &b= &2&lPossible lag incoming! &r-%s" % sender.getDisplayName())
else:
noperm(sender)
""" Something I'm planning for schematics
@hook.event("player.PlayerCommandPreprocessEvent", "low")
def on_command(event):
msg = " ".split(event.getMessage())
if len(msg) < 3:
return
if msg[0].lower() not in ("/schematic", "/schem"):
return
if msg[1].lower() not in ("save", "load"):
return
msg[2] = event.getPlayer().getName() + "/" + msg[2]
"""
+18 -18
View File
@@ -5,31 +5,31 @@ default_motd = colorify(server.getMotd())
motd = default_motd motd = default_motd
@hook.command("getmotd") @hook.command("getmotd")
def on_getmotd_command(sender, command, label, args): def on_getmotd_command(sender, args):
plugin_header(sender, "MOTD") plugin_header(sender, "MOTD")
msg(sender, motd, usecolor = False) msg(sender, motd, usecolor = False)
@hook.command("setmotd") @hook.command("setmotd")
def on_setmotd_command(sender, command, label, args): def on_setmotd_command(sender, args):
global motd global motd
if sender.hasPermission("utils.setmotd"): if sender.hasPermission("utils.setmotd"):
if not checkargs(sender, args, 1, -1): if not checkargs(sender, args, 1, -1):
return True return True
motd = colorify(" ".join(args).replace("\\n", "\n")) motd = colorify(" ".join(args).replace("\\n", "\n"))
if motd == "--reset": if motd == "--reset":
motd = default_motd motd = default_motd
broadcast(None, plugin_header(name="MOTD")) broadcast(None, plugin_header(name="MOTD"))
broadcast(None, "&aNew MOTD:&r\n%s" % motd) broadcast(None, "&aNew MOTD:&r\n%s" % motd)
broadcast(None, " ") broadcast(None, " ")
else: else:
noperm(sender) noperm(sender)
return True return True
@hook.event("server.ServerListPingEvent") @hook.event("server.ServerListPingEvent")
def on_server_ping(event): def on_server_ping(event):
event.setMotd(motd) event.setMotd(motd)
-5
View File
@@ -1,9 +1,4 @@
#pylint: disable = F0401 #pylint: disable = F0401
"""
A library that makes use of the so called ClassPathHack for jython
to allow proper loading of mysql-connector.jar at runtime.
Import only, no methods.
"""
import java.lang.reflect.Method import java.lang.reflect.Method
import java.io.File import java.io.File
import java.net.URL import java.net.URL
-37
View File
@@ -1,37 +0,0 @@
from helpers import *
##############################################################
# #
# This module automatically puts people in the corresponding #
# scoreboard team so that their name is colored properly and #
# tab will be nicely sorted. #
# #
##############################################################
ranks = ["visitor", "member", "builder", "trusted", "trainingmod", "mod", "admin"]
# prefixes are used for sorting in the tab list
prefixes = {"admin":"a", "mod":"b", "trainingmod":"c", "trusted":"d", "builder":"e", "member":"f","visitor":"g"}
@hook.event("player.PlayerJoinEvent", "low")
def on_player_join(event):
player = event.getPlayer()
team = get_team(player)
if team:
cmd = "scoreboard teams join %s %s" % (team, player.getName())
server.dispatchCommand(server.getConsoleSender(), cmd)
def get_rank(player):
player_rank = None
for rank in ranks:
if not player.hasPermission("group.%s" % rank):
break
player_rank = rank
if not player_rank:
warn("Couldn't find rank for player %s" % player.getName())
return player_rank
def get_team(player):
rank = get_rank(player)
if rank:
prefix = prefixes.get(rank)
return "_".join([prefix, rank])
-29
View File
@@ -1,29 +0,0 @@
from helpers import *
py_players = []
class py_player:
def __init__(self,player):
self.player = player
self.logging_in = False
self.login_time = 0
def get_py_player(player):
#py_player = py_players[py_players.index(player)]
for py_player in py_players:
if py_player.player.getName() == player.getName():
return py_player
@hook.event("player.PlayerJoinEvent","lowest")
def on_join(event):
player = py_player(event.getPlayer())
py_players.append(player)
print str(len(py_players))+event.getPlayer().getName()
@hook.event("player.PlayerQuitEvent","highest")
def on_leave(event):
py_players.remove(get_py_player(event.getPlayer()))
-192
View File
@@ -1,192 +0,0 @@
from helpers import *
import org.bukkit.entity.Player as Base_player
import blockplacemods as blockmods
import snowbrawl
import loginsecurity as login
import calc
import chatgroups as cg
import adminchat as ac
import cycle
import forcefield as ff
import imout
import mentio
import pmtoggle
get_info_perm = "utils.playermanager.info"
players = []
###############################################################
# Outside-accessible functions
def get_player(name):
for player in players:
if player.get_name() == name:
return player
return None
##############################################################
# Events
@hook.event("player.PlayerQuitEvent", "highest")
def on_quit(event):
for i in range(len(players)):
if players[i].get_uuid() == uid(event.getPlayer()):
players.remove(players[i])
return
@hook.event("player.PlayerJoinEvent", "highest")
def on_join(event):
players.append(Player(event.getPlayer()))
#############################################################
# Commands
def send(sender, name, data):
if isinstance(data, bool):
if data == True:
msg(sender, "&e-&a %s&e:&a True" % name)
else:
msg(sender, "&e-&a %s&e:&c False" % name)
else:
msg(sender, "&e-&a %s&e:&6 %s" % (name, str(data)))
def send_header(sender, name):
msg(sender, "&e- &2 %s&e:" % name.upper())
def print_info(sender, player):
send_header(sender, "general")
send(sender, "Name", player.get_name())
send(sender, "UUID", player.get_uuid())
send(sender, "Logged in", player.logged_in())
send_header(sender, "snowbrawl")
send(sender, "In arena", player.in_sb_arena())
send(sender, "Arena", player.get_sb_arena())
send_header(sender, "place-mods")
send(sender, "Slab flip", player.has_autoflip_slab())
send(sender, "Cauldron fill", player.has_autofill_cauldron())
send(sender, "Piston face", player.has_autoface_piston())
send_header(sender, "chat groups")
send(sender, "In chatgroup", player.in_cg())
send(sender, "Chatgroup", player.get_cg())
send(sender, "Key", player.get_cg_key())
send(sender, "Toggle", player.has_cg_toggle())
send_header(sender, "Admin chat")
send(sender, "In adminchat", player.in_ac())
send(sender, "Key", player.get_ac_key())
send(sender, "Toggle", player.has_ac_toggle())
send_header(sender, "forcefield")
send(sender, "Whitelist", "&e, &6".join(player.get_ff_whitelist()))
send(sender, "Toggle", player.has_ff_toggle())
send_header(sender, "miscellaneous")
send(sender, "Calc", player.has_calc())
send(sender, "PM toggle", player.has_pm_toggle())
send(sender, "Cycle toggle", player.has_cycle())
send(sender, "Imout toggle", player.has_imout_toggle())
send(sender, "Mentio", "&e, &6".join(player.get_mentio_list()))
@hook.command("getinfo")
def on_command(sender, cmd, label, args):
if sender.hasPermission(get_info_perm):
if len(args) != 1:
msg(sender, "&e-&a /getinfo <name>")
else:
player = get_player(args[0])
if player != None:
print_info(sender, player)
else:
msg(sender, "&e-&c Player not online or does not exist")
else:
noperm(sender)
return True
#############################################################
# Player class
class Player():
def __init__(self, player):
self.player = player
def get_java_player(self):
return self.player
def get_uuid(self):
return uid(self.player)
def get_name(self):
return self.get_java_player().getName()
def get_display_name(self):
return self.get_java_player().getDisplayName()
def in_sb_arena(self):
for arena in snowbrawl.arenas:
if arena.in_players(self.get_java_player()):
return True
return False
def get_sb_arena(self):
for arena in snowbrawl.arenas:
if arena.in_players(self.get_java_player()):
return arena
return None
def logged_in(self):
return self.get_name() not in login.logging_in
def has_autoflip_slab(self):
return blockmods.isEnabled("slab", self.get_uuid())
def has_autofill_cauldron(self):
return blockmods.isEnabled("cauldron", self.get_uuid())
def has_autoface_piston(self):
return blockmods.isEnabled("piston", self.get_uuid())
def has_calc(self):
return self.get_uuid() in calc.calc_users
def in_cg(self):
return self.get_uuid() in cg.groups.keys()
def get_cg(self):
if self.in_cg():
return cg.groups[self.get_uuid()]
else:
return None
def get_cg_key(self):
return cg.get_key(self.get_uuid())
def has_cg_toggle(self):
return self.get_uuid() in cg.cg_toggle_list
def in_ac(self):
return self.get_java_player().hasPermission(ac.ac_permission)
def get_ac_key(self):
return ac.get_key(self.get_uuid())
def has_ac_toggle(self):
return self.get_name() in ac.ac_toggle_list
def has_cycle(self):
return self.get_uuid() not in cycle.no_cyclers
def has_ff_toggle(self):
return self.get_uuid() in ff.ff_users
def get_ff_whitelist(self):
return ff.whitelists.get(self.get_uuid(), [])
def has_imout_toggle(self):
return self.get_name() in imout.imout_toggle_list
def get_mentio_list(self):
return mentio.get_keywords(self.get_java_player())
def has_pm_toggle(self):
return self.get_uuid() in pmtoggle.toggle_dict
+7 -9
View File
@@ -1,9 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
""" # this was going to be a PlotMe-like plugin "plotter"
*Very basic* start of a custom plot-plugin like PlotMe # but it seems like PlotMe is still beeing developed, so we don't need our own.
on hold because the PlotMe developer continued to develop PlotMe
"""
import sys import sys
@@ -12,15 +10,15 @@ z_plot_size = 3
padding = 1 padding = 1
def base_coords(x, z): def base_coords(x, z):
pid = plot_id(x, z) pid = plot_id(x, z)
return [pid[0] * (x_plot_size + padding), pid[1] * (z_plot_size + padding)] return [pid[0] * (x_plot_size + padding), pid[1] * (z_plot_size + padding)]
def bounds(x, z): def bounds(x, z):
base = base_coords(x, z) base = base_coords(x, z)
return [base, [base[0] + x_plot_size, base[1] + z_plot_size]] return [base, [base[0] + x_plot_size, base[1] + z_plot_size]]
def plot_id(x, z): def plot_id(x, z):
return [x // (x_plot_size + padding), z // (z_plot_size + padding)] return [x // (x_plot_size + padding), z // (z_plot_size + padding)]
x = int(sys.argv[1]) x = int(sys.argv[1])
+1 -2
View File
@@ -1,5 +1,4 @@
name: RedstonerUtils name: RedstonerUtils
main: main.py main: main.py
version: 3.1.0 version: 3.0.0
author: redstone_sheep author: redstone_sheep
-57
View File
@@ -1,57 +0,0 @@
from helpers import *
import org.bukkit.Bukkit as Bukkit
from java.util.UUID import fromString as juuid
toggle_dict = {}
permission = "utils.pmtoggle"
@hook.command("pmtoggle",
aliases = ["tm", "mt", "tmsg", "msgt", "pmt", "tpm"],
usage = "/<command> [player]",
description = "Toggle automatic sending of messages"
)
def on_toggle_message_command(sender, command, label, args):
if not sender.hasPermission(permission) or not is_player(sender):
noperm(sender)
return True
plugin_header(sender, "Private Message Toggle")
uuid = uid(sender)
if len(args) > 0:
if len(args) > 1:
msg(sender, "&cToo many arguments!")
return True
target = Bukkit.getPlayer(args[0])
if target:
toggle_dict[uuid] = uid(target)
msg(sender, "&2Enabled toggle so that you're now sending only to %s &2by default" % target.getDisplayName())
else:
msg(sender, "&cThat player could not be found")
elif uuid in toggle_dict:
del toggle_dict[uuid]
msg(sender, "&2Disabled toggle successfully")
else:
msg(sender, "&cExpected a player as argument")
return True
@hook.event("player.AsyncPlayerChatEvent", "normal")
def on_chat(event):
if event.isCancelled():
return
player = event.getPlayer()
uuid = uid(player)
if uuid in toggle_dict:
event.setCancelled(True)
target = Bukkit.getPlayer(juuid(toggle_dict[uuid])).getName()
runas(player, "msg %s %s" % (target, event.getMessage()))
@hook.event("player.PlayerQuitEvent", "normal")
def on_quit(event):
uuid = uid(event.getPlayer())
if uuid in toggle_dict:
del toggle_dict[uuid]
for pid in list(toggle_dict):
if toggle_dict[pid] == uuid:
del toggle_dict[pid]
msg(Bukkit.getPlayer(juuid(pid)), "%s &cwent off so your Private Message Toggle has been disabled!" % Bukkit.getPlayer(juuid(uuid)).getDisplayName())
-129
View File
@@ -1,129 +0,0 @@
from helpers import *
from java.util.UUID import fromString as juuid
import org.bukkit.Material as Material
spawn_world = "Spawn"
punish_world = "Punishments"
slave_perm = "utils.minerslaves"
slaves = []
def save_slaves():
buf = []
for slave in slaves:
buf.append(slave.get_data())
save_json_file("miner_slaves", buf)
def load_slaves():
buf = open_json_file("miner_slaves", [])
for data in buf:
slave = Slave(True, None, None)
slave.load_data(data)
slaves.append(slave)
def get_slave(player):
for slave in slaves:
if slave.get_uuid() == player:
return slave
return None
class Slave(object):
def __init__(self, from_file, player, amount):
if from_file:
self.players = None
self.blocks = None
return
slave = get_slave(uid(player))
if slave != None:
slave.set_blocks(slave.get_blocks() + amount)
else:
self.player = uid(player)
self.blocks = amount
slaves.append(self)
def get_uuid(self):
return self.player
def get_blocks(self):
return self.blocks
def set_blocks(self, amount):
self.blocks = amount
def update(self):
self.blocks -= 1
if self.blocks <= 0:
server.getPlayer(juuid(self.get_uuid())).teleport(server.getWorld(spawn_world).getSpawnLocation())
slaves.remove(self)
save_slaves()
def get_data(self):
return {
"player": self.player,
"amount": self.blocks
}
def load_data(self, data):
self.player = str(data["player"])
self.blocks = int(data["amount"])
load_slaves()
@hook.event("block.BlockBreakEvent", "low")
def event(event):
if event.getPlayer().getWorld().getName() != punish_world:
return
slave = get_slave(uid(event.getPlayer()))
if slave != None and event.getBlock().getType() == Material.OBSIDIAN:
slave.update()
@hook.command("miner")
def command(sender, cmd, label, args):
if not sender.hasPermission(slave_perm):
noperm(sender)
return True
if len(args) == 0 or (len(args) != 1 and args[0] == "list") or (len(args) != 2 and args[0] == "rem") or (len(args) != 3 and args[0] == "add"):
msg(sender, "&e-&a /miner add/rem/list <name> <amount>")
return True
if args[0] == "add":
try:
int(args[2])
except:
msg(sender, "&cArgument <amount> is not a number")
return True
if args[0] == "list":
if len(slaves) == 0:
msg(sender, "&e-&a There are no people mining obsidian")
return True
for slave in slaves:
msg(sender, "&e-&a %s: %s blocks" % (server.getOfflinePlayer(juuid(slave.get_uuid())).getName(), slave.get_blocks()))
return True
elif args[0] == "add":
player = server.getOfflinePlayer(str(args[1]))
if player.isOnline():
player.teleport(server.getWorld(punish_world).getSpawnLocation())
Slave(False, player, int(args[2]))
save_slaves()
msg(player, "&e-&a You have been punished, mine %s blocks of obsidian to get out!" % args[2])
msg(sender, "&e-&a Player %s has been added into punishments for %s blocks of obsidian" % (player.getName(), args[2]))
else:
msg(sender, "&cYou can only punish online players")
return True
elif args[0] == "rem":
player = server.getOfflinePlayer(str(args[1]))
if player.isOnline():
slave = get_slave(uid(player))
if slave != None:
server.getPlayer(juuid(slave.get_uuid())).teleport(server.getWorld(spawn_world).getSpawnLocation())
slaves.remove(slave)
save_slaves()
else:
msg(sender, "&e-&a Player not in punishments")
else:
msg(sender, "&cYou can only remove online players")
return True
else:
msg(sender, "&e-&a /miner add/rem/list <name> <amount>")
return True
+95 -156
View File
@@ -2,7 +2,6 @@ from helpers import *
from java.util.UUID import fromString as juuid from java.util.UUID import fromString as juuid
import time import time
import thread import thread
from traceback import format_exc as trace
time_format = "%Y.%m.%d %H:%M" time_format = "%Y.%m.%d %H:%M"
@@ -13,188 +12,128 @@ rp_permission = "utils.rp"
def print_help(sender): def print_help(sender):
msg(sender, " &2/report <text> &eReport something") msg(sender, " &2/report <text> &eReport something")
msg(sender, " &2/rp open &eList open reports (id, player, text)") msg(sender, " &2/rp list &eList unresolved reports (id, player, text)")
msg(sender, " &2/rp closed &eList closed reports (id, player, text)") msg(sender, " &2/rp tp <id> &eTeleport to report's location & show details")
msg(sender, " &2/rp tp <id> &eTeleport to report's location & show details") msg(sender, " &2/rp del <id> &eResolve a report")
msg(sender, " &2/rp close <id> &eResolve an open report")
msg(sender, " &2/rp reopen <id> &eReopen a resolved report")
msg(sender, " &2/rp del <id> &eDelete a report (admin only)")
def print_list(sender, closed): def print_list(sender):
try: # new thread, anything can happen. try: # new thread, anything can happen.
targeted_reports = dict(enumerate(reports)) msg(sender, "&a" + str(len(reports)) + " reports:")
for i in list(targeted_reports): for i, report in enumerate(reports):
report = targeted_reports[i] name = server.getOfflinePlayer(juuid(report["uuid"])).getName()
if report["closed"] != closed: msg(sender, "&8[&e%s&c%s&8] &3%s&f: &a%s" % (i, report["time"], name, report["msg"]))
targeted_reports.pop(i) except:
warn("Failed to complete report's print_list() thread")
msg(sender, "&a%s %s reports:" % (len(targeted_reports), "closed" if closed else "open"))
for i in targeted_reports:
report = targeted_reports[i]
name = retrieve_player(report["uuid"]).getName()
msg(sender, "&8[&e%s &c%s&8] &3%s&f: &a%s" % (i, report["time"], name, report["msg"]))
except:
warn("Failed to complete report's print_list() thread")
error(trace())
def tp_report(sender, rep_id): def tp_report(sender, rep_id):
if rep_id >= len(reports) or rep_id < 0: if rep_id >= len(reports) or rep_id < 0:
msg(sender, "&cReport &3#" + str(rep_id) + "&c does not exist!") msg(sender, "&cReport &3#" + str(rep_id) + "&c does not exist!")
else: return True
report = reports[rep_id] else:
safetp(sender, server.getWorld(report["world"]), report["x"], report["y"], report["z"], report["yaw"], report["pitch"]) report = reports[rep_id]
msg(sender, "&aTeleported to %s&areport #%s" % ("&cclosed " if report["closed"] else "", rep_id)) safetp(sender, server.getWorld(report["world"]), report["x"], report["y"], report["z"], report["yaw"], report["pitch"])
msg(sender, "&aTeleported to report #%s" % rep_id )
# resolve == True: You're resolving, False: reopening
def resolve_reopen_report(sender, rep_id, resolve):
action = "resolved" if resolve else "reopened"
report = edit_report(sender, rep_id)
if report != None:
if report["closed"] == resolve:
msg(sender, "&cReport &3#%s&c was already %s!" % (rep_id, action))
else:
report["closed"] = resolve
save_reports()
msg(sender, "&aReport #%s %s" % (rep_id, action))
message_reporter(sender, report, action)
def delete_report(sender, rep_id): def delete_report(sender, rep_id):
if not sender.hasPermission(rp_permission + ".del"): if len(reports) > rep_id >= 0:
noperm(sender) report = reports[rep_id]
return reports.pop(rep_id)
action = "&cdeleted" save_reports()
report = edit_report(sender, rep_id) msg(sender, "&aReport #%s deleted." % rep_id)
if report != None: reporter = server.getOfflinePlayer(juuid(report["uuid"]))
reports.remove(report) plugin_header(reporter, "Report")
save_reports() msg(reporter, "&aReport '&e%s&a' was resolved by %s." % (report["msg"], sender.getName()))
msg(sender, "&aReport #%s %s" % (rep_id, action)) else:
message_reporter(sender, report, action)
def edit_report(sender, rep_id):
if len(reports) > rep_id >= 0:
return reports[rep_id]
msg(sender, "&cThat report does not exist!") msg(sender, "&cThat report does not exist!")
return None
def message_reporter(sender, report, action):
reporter = get_reporter(report)
message = "&aReport '&e%s&a' was %s &aby %s." % (report["msg"], action, sender.getName())
if reporter.isOnline():
plugin_header(reporter, "Reports")
msg(reporter, message)
else:
server.dispatchCommand(sender, "mail send %s %s" % (reporter.getName(), colorify(message)))
def save_reports(): def save_reports():
save_json_file("reports", reports) save_json_file("reports", reports)
@hook.command("rp") @hook.command("rp")
def on_rp_command(sender, command, label, args): def on_rp_command(sender, args):
if sender.hasPermission(rp_permission): if sender.hasPermission(rp_permission):
plugin_header(sender, "Reports") plugin_header(sender, "Reports")
if len(args) > 0: if len(args) > 0:
subcmd = args[0].lower() if args[0] == "list":
if subcmd == "closed": # needs to run in seperate thread because of getOfflinePlayer
# needs to run in seperate thread because of getOfflinePlayer thread.start_new_thread(print_list, (sender))
thread.start_new_thread(print_list, (sender, True,)) else:
elif subcmd in ["open", "list"]: if not checkargs(sender, args, 2, 2):
thread.start_new_thread(print_list, (sender, False,)) return True
else: try:
if not checkargs(sender, args, 2, 2): repid = int(args[1])
return True except ValueError:
try: msg(sender, "&cDoesn't look like &3" + args[1] + "&c is a valid number!")
repid = int(args[1]) print_help(sender)
except ValueError: return True
msg(sender, "&cDoesn't look like &3" + args[1] + "&c is a valid number!") if args[0] == "tp":
print_help(sender) if not is_player(sender):
return True msg(sender, "&conly players can do this")
if subcmd == "tp": return True
if not is_player(sender): tp_report(sender, repid)
msg(sender, "&conly players can do this") elif args[0] == "del":
return True delete_report(sender, repid)
tp_report(sender, repid)
elif subcmd == "close":
resolve_reopen_report(sender, repid, True)
elif subcmd == "del":
delete_report(sender, repid)
elif subcmd == "reopen":
resolve_reopen_report(sender, repid, False)
else:
print_help(sender)
else: else:
print_help(sender) print_help(sender)
else: else:
noperm(sender) print_help(sender)
return True else:
noperm(sender)
return True
@hook.command("report") @hook.command("report")
def on_report_command(sender, command, label, args): def on_report_command(sender, args):
plugin_header(sender, "Report") plugin_header(sender, "Report")
if not is_player(sender): if not is_player(sender):
msg(sender, "&conly players can do this") msg(sender, "&conly players can do this")
return True
if not checkargs(sender, args, 1, -1):
return True
text = " ".join(args)
loc = sender.getLocation()
reporter = sender.name
reporter_id = uid(sender)
report = {
"uuid": reporter_id,
"msg": text,
"x": int(loc.x),
"y": int(loc.y),
"z": int(loc.z),
"yaw": int(loc.yaw),
"pitch": int(loc.pitch),
"world": loc.getWorld().name,
"time": time.strftime(time_format),
"closed": False
}
reports.append(report)
save_reports()
broadcast(rp_permission, "&aReport #" + str(len(reports) -1) + ": " + reporter + "&f: " + text)
msg(sender, "&aReported \"&e" + text + "&a\"")
return True return True
if not checkargs(sender, args, 1, -1):
return True
text = " ".join(args)
loc = sender.getLocation()
reporter = sender.name
reporter_id = uid(sender)
report = {
"uuid": reporter_id,
"msg": text,
"x": int(loc.x),
"y": int(loc.y),
"z": int(loc.z),
"yaw": int(loc.yaw),
"pitch": int(loc.pitch),
"world": loc.getWorld().name,
"time": time.strftime(time_format)
}
reports.append(report)
save_reports()
broadcast(rp_permission, "&aReport #" + str(len(reports) -1) + ": " + reporter + "&f: " + text)
msg(sender, "&aReported \"&e" + text + "&a\"")
return True
def reports_reminder(): # needs 2 args for unknown reason def reports_reminder(): # needs 2 args for unknown reason
while True: while True:
for i in range(0, check_delay*2): for i in range(0, check_delay*2):
time.sleep(0.5) # check every 0.5 seconds if we should kill the thread time.sleep(0.5) # check every 0.5 seconds if we should kill the thread
if not check_reports: if not check_reports:
info("Reports reminder thread killed.") info("Reports reminder thread killed.")
thread.exit() thread.exit()
targeted_reports = get_reports(False) if len(reports) > 0:
if len(targeted_reports) > 0: broadcast(rp_permission, "&2--=[ Reports ]=--")
broadcast(rp_permission, "&aThere are %s open reports!" % len(targeted_reports)) broadcast(rp_permission, "&aThere are %s pending reports!" % len(reports))
def stop_reporting(): def stop_reporting():
global check_reports global check_reports
info("Ending reports reminder thread") info("Ending reports reminder thread")
check_reports = False check_reports = False
def get_reports(closed):
targeted_reports = []
for report in reports:
if report["closed"] == closed:
targeted_reports.append(report)
return targeted_reports
def get_reporter(report):
return server.getOfflinePlayer(juuid(report["uuid"]))
thread.start_new_thread(reports_reminder, ()) thread.start_new_thread(reports_reminder, ())
+75 -74
View File
@@ -9,95 +9,96 @@ last_msg = 0
def save_lols(): def save_lols():
save_json_file("lol", lols) save_json_file("lol", lols)
def add_lol(txt): def add_lol(txt):
lols.append(txt) lols.append(txt)
save_lols() save_lols()
def del_lol(lid): def del_lol(lid):
lols.pop(lid) lols.pop(lid)
save_lols() save_lols()
def print_lol(sender, lid): def print_lol(sender, lid):
global last_msg global last_msg
if time() - last_msg > timeout: if time() - last_msg > timeout:
if len(lols) > lid: if len(lols) > lid:
dispname = sender.getDisplayName() if is_player(sender) else sender.getName() dispname = sender.getDisplayName() if is_player(sender) else sender.getName()
broadcast(None, "&8[&blol&8] &7%s&8: &e%s" % (dispname, lols[lid])) broadcast(None, "&8[&blol&8] &7%s&8: &e%s" % (dispname, lols[lid]))
last_msg = time() last_msg = time()
else:
msg(sender, "&cInvalid id")
else: else:
msg(sender, "&cYou can use SayLol again in &a%s seconds!" % int(timeout + 1 - (time() - last_msg))) plugin_header(sender, "SayLol")
msg(sender, "&cInvalid id")
else:
plugin_header(sender, "SayLol")
msg(sender, "&cYou can use SayLol again in &a%s seconds!" % int(timeout + 1 - (time() - last_msg)))
def search_lols(sender, keyword): def search_lols(sender, keyword):
if not keyword: if not keyword:
msg(sender, "&cPlease provide a keyword to search for!") msg(sender, "&cPlease provide a keyword to search for!")
return return
keyword = keyword.lower() msg(sender, "&aLols containing '&6%s&a':" % keyword)
msg(sender, "&aLols containing '&6%s&a':" % keyword) for i, lol in enumerate(lols):
for i, lol in enumerate(lols): if keyword in lol:
if keyword in lol.lower(): msg(sender, "&a%s: &e%s" % (str(i).rjust(3), lol))
msg(sender, "&a%s: &e%s" % (str(i).rjust(3), lol)) msg(sender, "") # empty line showing end of list
msg(sender, "") # empty line showing end of list
@hook.command("lol") @hook.command("lol")
def on_lol_command(sender, command, label, args): def on_lol_command(sender, args):
plugin_header(sender, "SayLol") plugin_header(sender, "SayLol")
cmd = args[0] if len(args) > 0 else None
if len(args) == 0:
if sender.hasPermission("utils.lol"):
print_lol(sender, randrange(len(lols)))
else:
noperm(sender)
elif cmd == "id":
if sender.hasPermission("utils.lol.id"):
try:
i = int(args[1])
print_lol(sender, i)
except ValueError:
msg(sender, "&cInvalid number '&e%s&c'" % args[1])
else:
noperm(sender)
elif cmd == "list":
for i in range(len(lols)):
msg(sender, "&a%s: &e%s" % (str(i).rjust(3), lols[i]))
elif cmd == "search":
if sender.hasPermission("utils.lol.search"):
search_lols(sender, " ".join(args[1:]))
else:
noperm(sender)
elif cmd == "add":
if sender.hasPermission("utils.lol.modify"):
add_lol(" ".join(args[1:]))
msg(sender, "&aNew lol message added!")
else:
noperm(sender)
elif cmd == "del":
if sender.hasPermission("utils.lol.modify"):
try:
i = int(args[1])
del_lol(i)
msg(sender, "&aLol message &e#%s&a deleted!" % i)
except ValueError:
msg(sender, "&cInvalid number '&e%s&c'" % args[1])
cmd = args[0] if len(args) > 0 else None
if len(args) == 0:
if sender.hasPermission("utils.lol"):
print_lol(sender, randrange(len(lols)))
else: else:
msg(sender, "&a/lol &eSay random message") noperm(sender)
msg(sender, "&a/lol list &eList all messages")
msg(sender, "&a/lol id <id> &eSay specific message") elif cmd == "id":
msg(sender, "&a/lol add <text> &eAdd message") if sender.hasPermission("utils.lol.id"):
msg(sender, "&a/lol del <id> &eDelete message") try:
return True i = int(args[1])
print_lol(sender, i)
except ValueError:
msg(sender, "&cInvalid number '&e%s&c'" % args[1])
else:
noperm(sender)
elif cmd == "list":
for i in range(len(lols)):
msg(sender, "&a%s: &e%s" % (str(i).rjust(3), lols[i]))
elif cmd == "search":
if sender.hasPermission("utils.lol.search"):
search_lols(sender, " ".join(args[1:]))
else:
noperm(sender)
elif cmd == "add":
if sender.hasPermission("utils.lol.modify"):
add_lol(" ".join(args[1:]))
msg(sender, "&aNew lol message added!")
else:
noperm(sender)
elif cmd == "del":
if sender.hasPermission("utils.lol.modify"):
try:
i = int(args[1])
del_lol(i)
msg(sender, "&aLol message &e#%s&a deleted!" % i)
except ValueError:
msg(sender, "&cInvalid number '&e%s&c'" % args[1])
else:
msg(sender, "&a/lol &eSay random message")
msg(sender, "&a/lol list &eList all messages")
msg(sender, "&a/lol id <id> &eSay specific message")
msg(sender, "&a/lol add <text> &eAdd message")
msg(sender, "&a/lol del <id> &eDelete message")
return True
-212
View File
@@ -1,212 +0,0 @@
from helpers import *
"""
Prints server restart message
arg 0 timeout
arg 1 $(whoami)
arg 2: reason
"""
@hook.command("script_restart")
def print_restart(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&2&l=============================================")
broadcast(None, "&r")
broadcast(None, "&r")
broadcast(None, "&9%s is restarting the server." % args[1])
broadcast(None, "&a&lServer is going to restart in %s seconds." % args[0])
broadcast(None, "&6&l%s" % " ".join(args[2:]))
broadcast(None, "&r")
broadcast(None, "&r")
broadcast(None, "&2&l=============================================")
else:
noperm(sender)
"""
Prints the server shut down message
arg 0 timeout
arg 1 $(whoami)
arg 2: reason
"""
@hook.command("script_stop")
def print_stop(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&2&l=============================================")
broadcast(None, "&r")
broadcast(None, "&r")
broadcast(None, "&9%s is shutting down the server." % args[1])
broadcast(None, "&a&lServer is going to shut down in %s seconds." % args[0])
broadcast(None, "&6&l%s" % " ".join(args[2:]))
broadcast(None, "&r")
broadcast(None, "&r")
broadcast(None, "&2&l=============================================")
else:
noperm(sender)
"""
Prints the shut down abort message
"""
@hook.command("script_stop_abort")
def abort_stop(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4&oShut down has been aborted.")
else:
noperm(sender)
"""
Prints the restart abort message
"""
@hook.command("script_restart_abort")
def abort_restart(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4&oRestart has been aborted.")
else:
noperm(sender)
"""
Prints the backup started message, saves all worlds and turns off world saving
"""
@hook.command("script_backup_begin")
def print_backup_begin(sender, command, lable, args):
if not is_player(sender):
broadcast(None, "&4 =&2 Starting backup now.")
server.dispatchCommand(server.getConsoleSender(), "save-all")
server.dispatchCommand(server.getConsoleSender(), "save-off")
else:
noperm(sender)
"""
Prints the backup finished message and turns on world saving
"""
@hook.command("script_backup_end")
def print_backup_end(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4 =&2 Backup completed.")
server.dispatchCommand(server.getConsoleSender(), "save-on")
else:
noperm(sender)
"""
Prints the backup error message and turns on world saving
"""
@hook.command("script_backup_error")
def print_backup_error(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4 =&c&l Error while backing up!")
server.dispatchCommand(server.getConsoleSender(), "save-on")
else:
noperm(sender)
"""
Prints the world trimming started message and starts trimming
"""
@hook.command("script_trim")
def print_backup_trim(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4 =&3 Deleting all chunks beyond border now.")
server.dispatchCommand(server.getConsoleSender(), "wb Creative trim 1000000 15")
server.dispatchCommand(server.getConsoleSender(), "wb trim confirm")
else:
noperm(sender)
"""
Prints the thimming finished message
arg 0 size difference of world
arg 1: world border trim data
"""
@hook.command("script_trim_result")
def print_backup_trim_res(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4 =&3 Chunk deletion saved %s (&a%sMB&3)" % (" ".join(args[1:]), args[0]))
else:
noperm(sender)
"""
Prints the database backup started message and admin-chat warning
"""
@hook.command("script_backup_database_begin")
def print_backup_db_begin(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&6 =&2 Starting database backup now.")
server.dispatchCommand(server.getConsoleSender(), "ac &aLogblock may be unavailable!")
else:
noperm(sender)
"""
Prints the database dumps compression started message
"""
@hook.command("script_backup_database_dumps")
def print_backup_db_dumps(sender, command, label, args):
if not is_player(sender):
server.dispatchCommand(server.getConsoleSender(), "ac &aDumps completed, logblock available again.")
server.dispatchCommand(server.getConsoleSender(), "ac &aNow compressing dumps, will take a while...")
else:
noperm(sender)
"""
Prints the database finished message and backup size in admin-chat
arg 0 size of backup
"""
@hook.command("script_backup_database_end")
def print_backup_db_end(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&6 =&2 Database backup completed.")
server.dispatchCommand(server.getConsoleSender(), "ac &abackup size: &2%sMB&a." % args[0])
else:
noperm(sender)
"""
Prints the database backup error message
"""
@hook.command("script_backup_database_error")
def print_backup_db_error(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&6 =&c&l Error while backing up database!")
else:
noperm(sender)
"""
Prints the database backup abort message
"""
@hook.command("script_backup_database_abort")
def print_backup_db_abort(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&6 =&2 Database backup aborted.")
else:
noperm(sender)
"""
Prints the spigot update message
"""
@hook.command("script_spigot_update")
def print_update(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&9 =&2 A new Spigot version has been downloaded!")
broadcast(None, "&9 =&2 Update will be applied after the next reboot.")
else:
noperm(sender)
"""
Prints the admin-chat warning for disk is filled
arg 0 fill percentage
"""
@hook.command("script_disk_filled")
def print_disk_filled(sender, command, label, args):
if not is_player(sender):
server.dispatchCommand(server.getConsoleSender(), "ac &4&lWARNING:&6 Disk is filled > 96% (" + args[0] + "%)")
server.dispatchCommand(server.getConsoleSender(), "ac &4 Server will shut down at 98%!")
server.dispatchCommand(server.getConsoleSender(), "ac &4 Contact an admin &nimmediately&4!")
else:
noperm(sender)
"""
Saves all worlds, kicks players and shuts down the server
arg 0: reason
"""
@hook.command("script_shutdown")
def shutdown(sender, command, label, args):
if not is_player(sender):
server.dispatchCommand(server.getConsoleSender(), "save-all")
server.dispatchCommand(server.getConsoleSender(), "kickall %s" % " ".join(args))
server.dispatchCommand(server.getConsoleSender(), "stop")
else:
noperm(sender)
-3
View File
@@ -1,3 +0,0 @@
mysql_database = "jdbc:mysql://localhost/database"
mysql_user = "username"
mysql_pass = "secret"
-115
View File
@@ -1,115 +0,0 @@
from helpers import *
import socket
import threading
import time
from java.lang import Runnable
from adminchat import adminchat
"""
Module to allow our servercontrol telnet server forward chat and speak in AC
"""
host = ""
port = 1122
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
try:
sock.bind((host,port))
sock.setblocking(True)
sock.listen(5)
except socket.error as e:
print(str(e))
def command_process(text):
text = list(text)
args = []
arg = ""
for char in text:
if char != " " and char != "\n" and char != "\r" and char != "\t":
arg += char
elif arg != "":
args.append(arg)
arg = ""
if arg != "":
args.append(arg)
return args
clients = []
clients_l = threading.Lock()
class client():
def __init__(self,conn,address,name):
self.conn = conn
self.address = address
self.name = name
with clients_l:
clients.append(self)
self.conn.setblocking(False)
self.client_thread = threading.Thread(target=self.client_t)
self.client_thread.daemon = True
self.client_thread.start()
def getName(self):
return self.name
def close_connection(self):
try:
self.conn.close()
with clients_l:
clients.remove(self)
except:
pass
def client_t(self):
while True:
time.sleep(0.1)
try:
data = self.conn.recv(1024)
except:
if self not in clients:
self.close_connection()
continue
if self not in clients: #If the connection was closed, kill the thread
break
adminchat(self,data)
def handle_conn():
while True:
try:
conn, address = sock.accept()
except:
time.sleep(0.1)
continue
#Send name
data = conn.recv(1024)
data = command_process(data)
print "servercontrol connected! %s " %data[0]
client_c = client(conn, address,data[0])
handle_conn_t = threading.Thread(target=handle_conn)
handle_conn_t.daemon = True
handle_conn_t.start()
@hook.event("player.AsyncPlayerChatEvent","low")
def on_chat(event):
sender = event.getPlayer().getName()
msg = event.getMessage()
for entry in clients:
entry.conn.sendall(sender + " " + msg)
-297
View File
@@ -1,297 +0,0 @@
from helpers import *
from basecommands import simplecommand, Validate
import org.bukkit.Material as Material
import java.util.UUID as UUID
import org.bukkit.Material as Material
import org.bukkit.block.BlockFace as BlockFace
blocked_cmds = tuple(shared["modules"]["misc"].sudo_blacklist) + ("pex", "kick", "ban", "tempban", "reload", "op", "deop", "whitelist")
def load_signs():
signs_obj = open_json_file("serversigns", [])
loaded = {}
for entry in signs_obj:
loaded[tuple(entry[:4])] = list(entry[4:])
return loaded
def save_signs():
signs_obj = []
for key, value in signs.iteritems():
signs_obj.append(key + tuple(value))
save_json_file("serversigns", signs_obj)
signs = load_signs() # {("world", x, y, z): ["owner_id", "msg1", "msg2"]}
lines = {} # Accumulated messages so players can have longer messages: {"Dico200": "Message...........", ""}
def fromLoc(bLoc):
"""
# Returns a tuple containing the (bukkit)location's world's name and its x, y and z coordinates
# The format for the tuple is ("world_name", x, y, z)
"""
return (bLoc.getWorld().getName(), bLoc.getBlockX(), bLoc.getBlockY(), bLoc.getBlockZ())
def equals(loc1, loc2):
"""
# Returns whether loc1 and loc2 represent the same block
"""
for i in range(4):
if loc1[i] != loc2[i]:
return False
return True
def getOwner(sign):
"""
# Returns the name of the sign its owner
"""
return retrieve_player(sign[0]).getName()
def isOwner(sign, player):
"""
# Returns whether the given player owns the sign
"""
return sign and sign[0] == uid(player)
def canEdit(sign, player):
"""
# Returns whether the given player can edit the sign.
# Returns False if the sign wasn't claimed.
"""
return (sign and player.hasPermission("utils.serversigns.admin")) or isOwner(sign, player)
def getSign(locAt):
"""
# If data was found for a sign at the given location, returns the data.
# This data follows the format of ["owner_id", "msg1", "msg2"...].
"""
for loc, sign in signs.iteritems():
if equals(locAt, loc):
return sign
return None
def identifySign(loc):
"""
# Returns a string from which the user can tell what sign you're talking about.
# The string follows the format of "sign at (x,y,z) in world_name".
"""
return "sign at (%s) in %s" % (",".join((str(i) for i in loc[1:])), loc[0])
def signsMsg(msg, colour = '4'):
"""
# Returns the given msg, prefixed with '[Signs] '.
# The given colour is after applied to the msg.
# The colour defaults to 4 (dark red).
"""
return "&c[Signs] &" + colour + msg
@simplecommand(cmd = "serversigns", aliases = ["svs", "signmsg"],
description = "Makes something happen when you right click signs. \nUse /svs help for more details.",
usage = "<claim|reset|add <msg>[++]|remove <ID>|clear|info|help>",
helpNoargs = True,
senderLimit = 0)
def svs_command(sender, command, label, args):
arg1 = args[0].lower()
Validate.isTrue(arg1 in ("claim", "reset", "add", "remove", "info", "clear", "help", "switch", "reverse", "unclaim"),
signsMsg("That argument could not be recognized, use &o/svs help &4for expected arguments"))
Validate.isAuthorized(sender, "utils.serversigns." + arg1)
#-------------------- Sub commands that don't require any conditions -----------------------
if arg1 == "help":
admin = sender.hasPermission("utils.serversigns.admin")
msg = signsMsg("Server signs lets you add messages to a sign.", 'a')
msg += "\nRight clicking the sign will display all the messages. Commands"
msg += "\ncan also be added, by prefixing the message with a '/'."
msg += "\nHow to use &b/serversigns&a:"
msg += "\n&b/svs claim" + ("" if not sender.hasPermission("utils.serversigns.admin") else " [owner]")
msg += "\n&a- Claims the sign so that you can add messages to it"
msg += "\n&b/svs info"
msg += "\n&a- Displays information about the (claimed) sign"
msg += "\n&b/svs add <message>[++]"
msg += "\n&a- Adds the message to the sign. Use ++ at the end"
msg += "\n&a- to add the message to your buffer. You can then use"
msg += "\n&a- the same command again to create a longer message."
msg += "\n&b/svs remove <message ID>"
msg += "\n&a- Removes the message with the given ID from the sign."
msg += "\n&a- The ID is given before each message by &b/svs info&a."
msg += "\n&b/svs switch|reverse <message ID 1> <message ID 2>"
msg += "\n&a- Reverses the order in which the given messages are shown."
msg += "\n&b/svs clear"
msg += "\n&a- Removes all messages from the sign."
msg += "\n&b/svs reset|unclaim"
msg += "\n&a- Resets the sign, removing all messages and its owner."
return msg
#-------------------------------------------------------------------------------------------
block = sender.getTargetBlock(None, 5)
Validate.isTrue(block.getType() in (Material.SIGN_POST, Material.WALL_SIGN), signsMsg("You have to be looking at a sign to use that!"))
loc = fromLoc(block.getLocation())
sign = getSign(loc)
signName = identifySign(loc)
arg2 = args[1].lower() if len(args) > 1 else None
#------------------------ Sub commands that require the block to be a sign -------------------------------
if arg1 == "claim":
Validate.isTrue(not sign, signsMsg("The %s was already claimed" % signName))
Validate.isTrue(can_build2(sender, block), signsMsg("You are not permitted to claim signs here"))
target = sender
if arg2:
Validate.isTrue(player.hasPermission("utils.serversigns.admin"), signsMsg("You are not authorized to claim signs for other players"))
target = server.getOfflinePlayer(arg2)
Validate.notNone(target, signsMsg("That player could not be found"))
Validate.isTrue(target.isOnline(), signsMsg("The target has to be online"))
uuid = uid(target)
if sign != None:
if sign[0] == uuid:
return signsMsg("The" + signName + " was already owned by that player")
else:
sign[0] = uuid
else:
signs[loc] = [uuid]
save_signs()
return signsMsg("Claimed the " + signName + ((" for %s" % target.getName()) if (target != sender) else ""), 'a')
#----------------------------------------------------------------------------------------------------------
Validate.notNone(sign, signsMsg("The %s has not been claimed" % signName))
#----------------------Sub commands that require the sign to be claimed as well------------------------------------
if arg1 == "info":
sign_lines = ""
for id, line in enumerate(sign[1:]):
sign_lines += ("\n &a%s: \"&f%s&a\"" % (id + 1, line))
return signsMsg("Properties of the %s:\n Owner: %s\n Lines: %s" % (signName, getOwner(sign), sign_lines), 'a')
#---------------------------------------------------------------------------------------------------------------
Validate.isTrue(canEdit(sign, sender), signsMsg("You do not own the %s!" % signName))
#---------------------- Sub commands that require you to own targeted sign as well -------------------------
if arg1 == "add":
line = " ".join(args[1:])
Validate.isTrue(line != "" and line != None, signsMsg("You have to enter a message to add or accumulate"))
key = sender.getName()
global lines
Validate.isTrue(key in lines or line[:1] != "/" or sender.hasPermission("utils.serversigns.command"), signsMsg("You cannot add commands to a sign!"))
if line[-2:] == "++":
if key not in lines:
lines[key] = ""
lines[key] += " " + line[:-2]
return signsMsg("Added given message to the message you're accumulating. \nYour accumulated message is now as follows: \n&f%s" % lines[key], 'a')
if key in lines:
line = (lines[key] + " " + line)[1:]
Validate.isTrue(line[0] != "/" or line.split(" ")[0][1:] not in blocked_cmds, signsMsg("Usage of that command with server signs is prohibited"))
sign.append(colorify(line) if line[0] != "/" else line)
save_signs()
return signsMsg("Added line \"&f%s&a\" to the %s" % (line, signName), 'a')
if arg1 == "remove":
Validate.notNone(arg2, signsMsg("You have to enter the ID of the message to remove!"))
try:
id = int(arg2)
except:
return signsMsg("The ID of the message has to be a number and can be found by using &o/svs info")
Validate.isTrue(id != 0 and id < len(sign), signsMsg("The %s has no message with an ID of %s, use &o/svs info &4for all messages." % (signName, id)))
del sign[id]
return signsMsg("Removed message with id %s from the %s" % (id, signName), 'a')
if arg1 in ("switch", "reverse"):
Validate.isTrue(len(args) == 3, signsMsg("You have to enter the 2 IDs of the messages to reverse"))
try:
id1 = int(args[1])
id2 = int(args[2])
except:
return signsMsg("The ID of the message has to be a number and can be found by using &o/svs info")
for id in (id1, id2):
Validate.isTrue(id != 0 and id < len(sign), signsMsg("The %s has no message with an ID of %s, use &o/svs info &4for all messages." % (signName, id)))
sign[id1], sign[id2] = sign[id2], sign[id1]
save_signs()
return signsMsg("Reversed the messages with IDs %s and %s of the %s" % (id1, id2, signName), 'a')
if arg1 == "clear":
signs[loc] = [sign[0]]
save_signs()
return signsMsg("Removed all messages from the %s" % signName, 'a')
if arg1 in ("reset", "unclaim"):
del signs[loc]
save_signs()
return signsMsg("Removed all messages and the owner from the %s, it can now be claimed" % signName, 'a')
#-------------------------------------------------------------------------------------------------------
@hook.event("player.PlayerInteractEvent")
def on_click(event):
if str(event.getAction()) != "RIGHT_CLICK_BLOCK":
return
block = event.getClickedBlock()
if block.getType() not in (Material.WALL_SIGN, Material.SIGN_POST):
return
sign = getSign(fromLoc(block.getLocation()))
if sign != None:
player = event.getPlayer()
for message in sign[1:]:
if message[:1] == "/":
server.dispatchCommand(player, message[1:])
else:
msg(player, message, usecolor = False)
# ---------------------------Sign breaking--------------------------------
checking_block = False
faces = {
BlockFace.NORTH : (0,1,2,),
BlockFace.SOUTH : (3,),
BlockFace.WEST : (4,),
BlockFace.EAST : (5,),
}
@hook.event("block.BlockBreakEvent", "monitor")
def on_break(event):
try:
global checking_block
if checking_block or event.isCancelled():
return
block = event.getBlock()
if block.getType() in (Material.SIGN_POST, Material.WALL_SIGN):
check_sign(event, block, attached = False)
for block_face, data_values in faces.iteritems():
block2 = block.getRelative(block_face)
if block2.getType() == Material.WALL_SIGN and block2.getData() in data_values:
check_sign(event, block2)
block3 = block.getRelative(BlockFace.UP)
if block3.getType() == Material.SIGN_POST:
check_sign(event, block3)
except:
error(trace())
def check_sign(event, block, attached = True):
player = event.getPlayer()
sign = getSign(fromLoc(block.getLocation()))
if not can_build2(player, block):
event.setCancelled(True)
msg(event.getPlayer(), signsMsg("You cannot break %s" % ("the sign attached to that block" if attached else "that sign")))
else:
loc = fromLoc(block.getLocation())
del signs[loc]
save_signs()
msg(player, signsMsg("Reset the %s which you just broke" % identifySign(loc)))
def can_build2(player, block):
global checking_block
event = BlockBreakEvent(block, player)
checking_block = True
server.getPluginManager().callEvent(event)
checking_block = False
return not event.isCancelled()
-175
View File
@@ -1,175 +0,0 @@
#!/usr/bin/env bash
# exit on failure
set -e
for cmd in curl java unzip git pip; do
if ! which "$cmd" >/dev/null; then
tput setf 4 >&2
echo "Error: please install '$cmd' to proceed" >&2
tput sgr0 >&2
exit 1
fi
done
echo -e "> This will only set up Spigot and all the plugins, configuration files are still up to you to manage"
echo -e "> Press enter to coninue"
read
mkdir -v "redstoner"
cd "redstoner"
mkdir -v "server"
mkdir -v "build"
cd "build"
echo -e "\n> Downloading Spigot build tools"
curl --progress-bar -Lo "BuildTools.jar" "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"
echo -e "\n> Building Spigot, this will take a while ..."
java -jar BuildTools.jar > /dev/null
cp -v spigot-*.jar "../server/spigot.jar"
rm spigot-*.jar
cd "../server/"
mkdir -v "plugins"
cd "plugins"
echo ">> Downloading essentials.jar ..."
curl --progress-bar -Lo "essentials.jar" "https://github.com/RedstonerServer/Essentials/releases/download/stable-2.9.6-REDSTONER/Essentials-2.x-REDSTONER.jar"
echo ">> Downloading essentialschat.jar ..."
curl --progress-bar -Lo "essentialschat.jar" "https://hub.spigotmc.org/jenkins/job/Spigot-Essentials/lastSuccessfulBuild/artifact/EssentialsChat/target/EssentialsChat-2.x-SNAPSHOT.jar"
echo ">> Downloading imageonmap.jar ..."
curl --progress-bar -Lo "imageonmap.jar." "https://dev.bukkit.org/media/files/772/680/imageonmap.jar"
echo ">> Downloading logblock.jar ..."
curl --progress-bar -Lo "logblock.jar." "https://dev.bukkit.org/media/files/757/963/LogBlock.jar"
echo ">> Downloading logblockquestioner.zip ..."
curl --progress-bar -Lo "logblockquestioner.zip" "https://cloud.github.com/downloads/DiddiZ/LogBlockQuestioner/LogBlockQuestioner%20v0.03.zip"
echo ">> Downloading multiverse-core.jar ..."
curl --progress-bar -Lo "multiverse-core.jar" "https://dev.bukkit.org/media/files/588/781/Multiverse-Core-2.4.jar"
echo ">> Downloading multiverse-portals.jar ..."
curl --progress-bar -Lo "multiverse-portals.jar." "https://dev.bukkit.org/media/files/588/790/Multiverse-Portals-2.4.jar"
echo ">> Downloading multiverse-netherportals.jar ..."
curl --progress-bar -Lo "multiverse-netherportals.jar." "https://dev.bukkit.org/media/files/589/64/Multiverse-NetherPortals-2.4.jar"
echo ">> Downloading multiverse-inventories.jar ..."
curl --progress-bar -Lo "multiverse-inventories.jar." "https://dev.bukkit.org/media/files/663/303/Multiverse-Inventories-2.5.jar"
echo ">> Downloading permissionsex.jar ..."
curl --progress-bar -Lo "permissionsex.jar" "https://dev.bukkit.org/media/files/882/992/PermissionsEx-1.23.3.jar"
echo ">> Downloading plotme.jar ..."
curl --progress-bar -Lo "plotme.jar" "http://ci.worldcretornica.com/job/PlotMe-Core/244/artifact/target/PlotMe-Core.jar"
echo ">> Downloading plotme-defaultgenerator.jar ..."
curl --progress-bar -Lo "plotme-defaultgenerator.jar" "http://ci.worldcretornica.com/job/PlotMe-DefaultGenerator/83/artifact/target/PlotMe-DefaultGenerator.jar"
echo ">> Downloading serversigns.jar ..."
curl --progress-bar -Lo "serversigns.jar." "https://dev.bukkit.org/media/files/876/381/ServerSigns.jar"
echo ">> Downloading redstoneclockdetector.jar ..."
curl --progress-bar -Lo "redstoneclockdetector.jar." "https://dev.bukkit.org/media/files/577/253/RedstoneClockDetector.jar"
echo ">> Downloading vault.jar ..."
curl --progress-bar -Lo "vault.jar" "https://dev.bukkit.org/media/files/837/976/Vault.jar"
echo ">> Downloading worldborder.jar ..."
curl --progress-bar -Lo "worldborder.jar." "https://dev.bukkit.org/media/files/883/629/WorldBorder.jar"
echo ">> Downloading worldguard.jar ..."
curl --progress-bar -Lo "worldguard.jar." "https://github.com/RedstonerServer/WorldGuard/releases/download/6.0.0-redstoner/worldguard-6.0.0-REDSTONER.jar"
echo ">> Downloading worldedit.jar ..."
curl --progress-bar -Lo "worldedit.jar" "https://dev.bukkit.org/media/files/880/435/worldedit-bukkit-6.1.jar"
echo ">> Downloading pythonpluginloader.jar ..."
curl --progress-bar -Lo "pythonpluginloader.jar" "https://bamboo.gserv.me/browse/PLUG-PYPL/latestSuccessful/artifact/JOB1/Version-agnostic-jar/PyPluginLoader.jar"
echo -e "\n> Unpacking LogBlockQuestioner"
unzip -q "logblockquestioner.zip" "LogBlockQuestioner.jar"
rm "logblockquestioner.zip"
mv -v "LogBlockQuestioner.jar" "logblockquestioner.jar."
echo -e "\n> Pulling redstoner-utils ..."
git clone -q "git@github.com:RedstonerServer/redstoner-utils.git" "redstoner-utils.py.dir" > /dev/null
echo -e "\n> Installing dependencies"
pip install passlib
echo -e "\n> All plugins downloaded"
cd "redstoner-utils.py.dir"
echo -e "\n> Duplicating sample files"
for file in ./*.example; do
cp -v "$file" "$(echo "$file" | rev | cut -d "." -f 2- | rev)"
done
cd "../.."
mkdir -v "lib"
cd "lib"
echo -e "\n> Downloading MySQL Connector ..."
curl --progress-bar -Lo "mysql-connector.zip" "https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.36.zip"
echo "> Extracting MySQL Connector"
unzip -p mysql-connector.zip "mysql-connector-java-5.1.36/mysql-connector-java-5.1.36-bin.jar" > mysql-connector.jar
rm "mysql-connector.zip"
cd ".."
echo -e "\n> Creating startup script"
cat > start.sh <<EOF
#!/usr/bin/env bash
java -Xms512m -Xmx1g -jar spigot.jar
EOF
chmod +x start.sh
port="25565"
re='^[0-9]+$'
if [[ "$1" =~ $re ]]; then
port="$1"
fi
echo "> Setting port to $port"
echo "> Generating server.properties"
cat > server.properties <<EOF
#Minecraft server properties
#Sat Jul 25 15:42:21 CEST 2015
spawn-protection=16
generator-settings=
force-gamemode=false
allow-nether=true
gamemode=1
broadcast-console-to-ops=true
enable-query=false
player-idle-timeout=0
difficulty=1
spawn-monsters=true
op-permission-level=4
resource-pack-hash=
announce-player-achievements=true
pvp=true
snooper-enabled=true
level-type=FLAT
hardcore=false
enable-command-block=false
max-players=20
network-compression-threshold=256
max-world-size=29999984
server-port=$port
server-ip=
spawn-npcs=true
allow-flight=false
level-name=world
view-distance=10
resource-pack=
spawn-animals=true
white-list=false
generate-structures=true
online-mode=true
max-build-height=256
level-seed=
use-native-transport=true
motd=Redstoner dev server
enable-rcon=false
EOF
echo -e "> Generating eula.txt"
echo "eula=true" > eula.txt
echo -e "\n> $(tput setf 2)All Done! $(tput sgr0)Don't forget to configure plugins for your needs."
echo "> Run redstoner/server/start.sh to start the server"
echo "> Our plugins are in redstoner/server/plugins/redstoner-utils.py.dir"
-159
View File
@@ -1,159 +0,0 @@
from helpers import *
import org.bukkit.inventory.ItemStack as ItemStack
import org.bukkit.Material as Material
from math import ceil
from basecommands import simplecommand, Validate, CommandException
""" Suggestion by Armadillo28, see thread: http://redstoner.com/forums/threads/2213?page=1#reply-14507 """
disallowed_item_types = (
Material.getMaterial(0),
Material.getMaterial(175),
Material.getMaterial(383),
)
default_args = open_json_file("signalstrengthdefaults", {})
def save_defaults():
save_json_file("signalstrengthdefaults", default_args)
def item_name(item_type, remove_underscores = True):
typ = str(item_type).lower()
return typ.replace("_", "") if remove_underscores else typ
def item_type_allowed(item_type):
return not item_type in disallowed_item_types
def required_item_count(strength, stack_size, slot_count):
if strength == 0:
item_count = 0
elif strength == 1:
item_count = 1
else:
item_count = int(ceil(slot_count * stack_size / 14.0 * (strength - 1)))
resulting_strength = 0 if item_count == 0 else int(1 + 14.0 * item_count / stack_size / slot_count)
#Clarification on these formulas at http://minecraft.gamepedia.com/Redstone_Comparator#Containers
return item_count if resulting_strength == strength else None
def get_data(player, args):
uuid = uid(player)
if uuid in default_args:
strength, item_type, item_data = default_args[uuid]
item_type = Material.getMaterial(item_type)
else:
strength = 1
item_type = Material.REDSTONE
item_data = 0
if len(args) > 0:
Validate.isTrue(args[0].isdigit() and 0 <= int(args[0]) <= 15, "&cThe signal strength has to be a value from 0 to 15")
strength = int(args[0])
if len(args) > 1:
if args[1].isdigit():
item_type = Material.getMaterial(int(args[1]))
else:
item_type = Material.matchMaterial(args[1])
Validate.notNone(item_type, "&cThat item type could not be found")
Validate.isTrue(item_type not in disallowed_item_types, "&cThat item type may not be used")
if len(args) > 2:
Validate.isTrue(args[2].isdigit() and 0 <= int(args[2]) <= 15, "&cThe data has to be a value from 0 to 15")
item_data = int(args[2])
return (strength, item_type, item_data)
def get_inventory(block):
try:
return block.getState().getInventory()
except AttributeError:
return None
def get_entire_container(container):
container_blocks = [container]
container_type = container.getType()
if container_type in (Material.CHEST, Material.TRAPPED_CHEST):
loc = container.getLocation()
x = loc.getBlockX()
y = loc.getBlockY()
z = loc.getBlockZ()
world = loc.getWorld()
container_blocks += [
block for block in (
world.getBlockAt(x + 1, y, z),
world.getBlockAt(x - 1, y, z),
world.getBlockAt(x, y, z + 1),
world.getBlockAt(x, y, z - 1),
) if block.getType() == container_type
]
return container_blocks
@simplecommand("signalstrength",
usage = "(default) [signalstrength] [item] [data]",
aliases = ["ss", "level"],
description = "Fills the targeted container with the correct amount of items to achieve the desired signal strength.",
amin = 0,
amax = 4,
helpSubcmd = True,
senderLimit = 0)
def on_signalstrength_command(sender, command, label, args):
if len(args) > 0 and args[0].lower() in ("default", "defaults", "setdefaults"):
strength, item_type, item_data = get_data(sender, args[1:])
uuid = uid(sender)
if strength == 1 and item_type == Material.REDSTONE and item_data == 0:
if uuid in default_args:
del default_args[uuid]
save_defaults()
else:
default_args[uuid] = (strength, str(item_type), item_data)
save_defaults()
return "&aSet your signal strength defaults to (%s, %s, %s)" % (strength, item_name(item_type, False), item_data)
Validate.isTrue(len(args) <= 3, "&cExpected at most 3 arguments")
target_block = sender.getTargetBlock(None, 5)
Validate.notNone(target_block, "&cThat command can only be used when a container is targeted")
inventory = get_inventory(target_block)
Validate.notNone(inventory, "&cThat command can only be used if a container is targeted")
strength, item_type, item_data = get_data(sender, args)
#--------Get the stack size and required amount of items to achieve the desired signal strength---------
stack_size = item_type.getMaxStackSize()
slot_count = inventory.getSize()
item_count = required_item_count(strength, stack_size, slot_count)
Validate.notNone(item_count, "&cThe desired signal strength could not be achieved with the requested item type")
#--------Add the other side of the chest if target is a double chest and check if player can build---------
container_blocks = get_entire_container(target_block)
for block in container_blocks:
Validate.isTrue(can_build(sender, block), "&cYou do not have permission to do that here")
#----------------Insert items-------------
full_stack_count, remaining = divmod(item_count, stack_size)
for block in container_blocks:
inv = block.getState().getInventory()
inv.clear()
for i in range(full_stack_count):
inv.setItem(i, ItemStack(item_type, stack_size, item_data))
if remaining > 0:
inv.setItem(full_stack_count, ItemStack(item_type, remaining, item_data))
return "&aComparators attached to that %s will now put out a signal strength of %s" % (item_name(target_block.getType()), strength)
+10 -10
View File
@@ -4,13 +4,13 @@ from helpers import msg
@hook.event("player.PlayerInteractEvent", "monitor") @hook.event("player.PlayerInteractEvent", "monitor")
def on_block_interact(event): def on_block_interact(event):
if (str(event.getAction()) == "RIGHT_CLICK_BLOCK"): if (str(event.getAction()) == "RIGHT_CLICK_BLOCK"):
sender = event.getPlayer() sender = event.getPlayer()
block = event.getClickedBlock().getState() block = event.getClickedBlock().getState()
if (isinstance(block, bukkit.block.Skull) and not event.isCancelled()): if (isinstance(block, bukkit.block.Skull) and not event.isCancelled()):
owner = block.getOwner() owner = block.getOwner()
if (owner): if (owner):
msg(sender, "&eThat's %s." % owner) msg(sender, "&eThat's %s." % owner)
else: else:
msg(sender, "&cThis skull has no name (Steve)") msg(sender, "&cThis skull has no name (Steve)")
event.setCancelled(True) event.setCancelled(True)
-969
View File
@@ -1,969 +0,0 @@
#Snowbrawl
from helpers import *
import time, threading, copy
import org.bukkit.inventory.ItemStack as ItemStack
import org.bukkit.Material as Material
import org.bukkit.potion.PotionEffect as PotionEffect
import org.bukkit.potion.PotionEffectType as PotionEffectType
from java.lang import Runnable
from java.util.UUID import fromString as juuid
from operator import __contains__
from traceback import format_exc as trace
import random
from synchronize import make_synchronized
#file names
file = "snowbrawl"
#permissions
list_perm = "utils.snowbrawl.list"
modify_perm = "utils.snowbrawl.modify"
teleport_perm = "utils.snowbrawl.tp"
create_perm = "utils.snowbrawl.create"
info_perm = "utils.snowbrawl.info"
join_perm = "utils.snowbrawl.join"
quit_perm = "utils.snowbrawl.quit"
#commands - tp command does not exist
list_command = "list"
del_command = "del"
set_command = "set"
name_command = "name"
pos_command = "pos"
create_command = "create"
info_command = "info"
modify_command = "modify"
modify_command_alias = "m"
quit_command = "quit"
class Arena(object):
def __init__(self, name):
self.queue = Queue()
self.name = name
self.refill = None
self.player_limit = None
self.start_time = None
self.match_goal = None # amount of deaths or time until the match ends (depends on arena_type)
self.arena_type = None # arena type (death or time)
self.explosion_damage = None
self.player_stats = {}
self.players = Queue()
self.spawn_location = []
self.respawn_location = []
self.sign_location = []
self.sign_click = []
self.corner1 = None # The corner1 given by the player (really bad for 3D position compare)
self.corner2 = None # The corner2 given by the player (really bad for 3D position compare)
self.tpp = None # The top, positive x, positive z corner
self.bnn = None # The bottom, negative x, negative z corner
#set corners of arena
def set_corner(self, sender, type):
loc = sender.getLocation()
if type == "1":
self.corner1 = Coords(loc)
elif type == "2":
self.corner2 = Coords(loc)
msg(sender, "&a-&e Arena corner %s set" % type)
self.update_corner_points()
#Compares the corner1 and corner2 locations and figures out tpp and bnn so that we dont have to do it everytime we run in_arena()
def update_corner_points(self):
self.tpp = None
self.bnn = None
if self.corner1 == None or self.corner2 == None:
return
corn1 = self.corner1.get_location()
corn2 = self.corner2.get_location()
if not corn1.getWorld().getName() == corn2.getWorld().getName():
return
top = corn1.y if corn1.y > corn2.y else corn2.y
bottom = corn1.y if corn1.y < corn2.y else corn2.y
pos_x = corn1.x if corn1.x > corn2.x else corn2.x
pos_z = corn1.z if corn1.z > corn2.z else corn2.z
neg_x = corn1.x if corn1.x < corn2.x else corn2.x
neg_z = corn1.z if corn1.z < corn2.z else corn2.z
self.tpp = Coords(corn1.getWorld(), pos_x, top, pos_z, 0, 0)
self.bnn = Coords(corn2.getWorld(), neg_x, bottom, neg_z, 0, 0)
#add sign to sign list
def add_sign(self, sender, name):
mats = set()
mats = None
block = sender.getTargetBlock(mats, 3).getState()
if isinstance(block, bukkit.block.Sign):
self.sign_click.append(NamedCoords(name, Coords(block.getLocation())))
msg(sender, "&a-&e Arena tp sign %s created and set" % name)
#Delete a sign from the sign list
def del_sign(self, sender, name):
for sign in self.sign_click:
if sign.get_name() == name:
self.sign_click.remove(sign)
msg(sender, "&a-&e Arena tp sign %s removed" % sign.get_name())
return
msg(sender, "&a-&e Arena tp sign with this name doesn't exist")
#Adds a player to the queue if they aren't already there.
def add_player(self, player):
if not self.queue.contains(player):
self.queue.put(player)
self.start_match()
return True
return False
#remove a player from the queue
def remove_player(self, player):
if self.queue.contains(player):
self.queue.remove(player)
return True
return False
#return true if loc is inside the arena boundries
def in_arena(self, loc):
if self.tpp == None or self.bnn == None:
return False
loc_tpp = self.tpp.get_location()
loc_bnn = self.bnn.get_location()
if loc.y > loc_tpp.y:
return False
if loc.y < loc_bnn.y:
return False
if loc.x > loc_tpp.x:
return False
if loc.x < loc_bnn.x:
return False
if loc.z > loc_tpp.z:
return False
if loc.z < loc_bnn.z:
return False
return True
def get_respawn(self):
id = random.randint(0, len(self.respawn_location) - 1)
return self.respawn_location[id]
def spawn_player(self, player):
id = random.randint(0, len(self.spawn_location) - 1)
loc = self.spawn_location[id].get_location().get_location()
safetp(player, loc.getWorld(), loc.x, loc.y, loc.z, loc.yaw, loc.pitch)
#Start match
def start_match(self):
if self.player_limit == None or self.match_goal == None or self.arena_type == None or len(self.spawn_location) == 0 or len(self.respawn_location) == 0 or len(self.sign_location) == 0:
return
if len(self.queue.read()) >= self.player_limit and len(self.players.read()) == 0:
self.start_time = time.time()
for i in range(self.player_limit):
player = self.queue.get()
self.players.put(player)
for player in self.players.read():
self.player_stats[player.getName() + "_deaths"] = 0
self.spawn_player(player)
msg(player, "&6The match has started!")
def bubbleSort(self, alist):
for passnum in range(len(alist)-1,0,-1):
for i in range(passnum):
if self.player_stats[alist[i].getName()+"_deaths"]>self.player_stats[alist[i+1].getName()+"_deaths"]:
temp = alist[i]
alist[i] = alist[i+1]
alist[i+1] = temp
return alist
@make_synchronized #Jython synchronized block
def end_match(self): #End match, sort the players and print the 3 players with least amount of deaths
sorted_list = self.bubbleSort(self.players.read())
for player in self.players.read():
if player.isOnline():
loc = self.sign_location[0].get_location().get_location()
safetp(player, loc.getWorld(), loc.x, loc.y, loc.z, loc.yaw, loc.pitch)
msg(player, "&6================= Match over =================")
msg(player, "&c&c")
if not len(sorted_list) < 1:
msg(player, "&e1. %s (%s)" % (sorted_list[0].getName(), self.player_stats[sorted_list[0].getName()+"_deaths"]))
if not len(sorted_list) < 2:
msg(player, "&e2. %s (%s)" % (sorted_list[1].getName(), self.player_stats[sorted_list[1].getName()+"_deaths"]))
if not len(sorted_list) < 3:
msg(player, "&e3. %s (%s)" % (sorted_list[2].getName(), self.player_stats[sorted_list[2].getName()+"_deaths"]))
msg(player, "&c&c")
msg(player, "&e Your deaths:&6 %s" % str(self.player_stats[player.getName() + "_deaths"]))
msg(player, "&c&c")
msg(player, "&6==============================================")
self.players.clear()
self.player_stats = {}
self.start_match()
def check_deaths(self):
if self.arena_type == "death":
for player in self.players.read():
if self.player_stats[player.getName() + "_deaths"] >= self.match_goal:
return True
return False
def is_running(self):
if len(self.players.read()) == 0:
return False
return True
def set_explosion_damage(self, dmg):
self.explosion_damage = dmg
def get_explosion_damage(self):
if self.explosion_damage == None:
return 1
return self.explosion_damage
def in_players(self, player):
return self.players.contains(player)
def set_player_limit(self, limit):
self.player_limit = limit
def set_end_goal(self, value):
self.match_goal = value
def set_type(self, type):
self.arena_type = type
def get_name(self):
return self.name
def set_refill(self, amount):
self.refill = int(amount)
def set_name(self, name):
self.name = name
def get_refill(self):
if self.refill == None:
return 16
return self.refill
def get_tp_signs(self):
return self.sign_location
def get_click_signs(self):
return self.sign_click
#Check if player is in the queue
def in_queue(self,player):
if self.queue.contains(player):
return True
return False
#Returns queue contents in list. use "".join(queue) to get a string
def get_queue_contents(self):
return self.queue.read()
#Returns queue object
def get_queue(self):
return self.queue
#Returns list of location objects of type, type.
def get_location(self, type):
if type == "spawn":
return self.spawn_location
elif type == "respawn":
return self.respawn_location
elif type == "sign":
return self.sign_location
#Add a location to list of type location
def add_location(self, name, location, type):
named_loc = NamedCoords(name, Coords(location))
if type == "spawn":
self.spawn_location.append(named_loc)
elif type == "respawn":
self.respawn_location.append(named_loc)
elif type == "sign":
self.sign_location.append(named_loc)
#Change location of location of type, type
def change_location(self, name, location, type):
if type == "spawn":
for spawn in self.spawn_location:
if spawn.get_name() == name:
spawn.get_location().set_location(location)
break
elif type == "respawn":
for respawn in self.respawn_location:
if respawn.get_name() == name:
respawn.get_location().set_location(location)
break
elif type == "sign":
for sign in self.sign_location:
if sign.get_name() == name:
sign.get_location().set_location(location)
break
#Remove location out of location
def delete_location(self, name, type):
if type == "spawn":
for spawn in self.spawn_location[:]:
if spawn.get_name() == name:
self.spawn_location.remove(spawn)
break
elif type == "respawn":
for respawn in self.respawn_location[:]:
if respawn.get_name() == name:
self.respawn_location.remove(respawn)
break
elif type == "sign":
for sign in self.sign_location[:]:
if sign.get_name() == name:
self.sign_location.remove(sign)
break
def get_data(self):
spawns = []
for spawn in self.spawn_location:
spawns.append(spawn.get_data())
respawns = []
for respawn in self.respawn_location:
respawns.append(respawn.get_data())
signs = []
for sign in self.sign_location:
signs.append(sign.get_data())
sign_clicks = []
for click in self.sign_click:
sign_clicks.append(click.get_data())
corners = []
corners.append(self.corner1.get_data() if not self.corner1 == None else None)
corners.append(self.corner2.get_data() if not self.corner2 == None else None)
corners.append(self.tpp.get_data() if not self.tpp == None else None)
corners.append(self.bnn.get_data() if not self.bnn == None else None)
data = {
"spawns": spawns,
"respawns": respawns,
"signs": signs,
"clicks": sign_clicks,
"corners": corners,
"explosion": self.explosion_damage,
"players": self.player_limit,
"refill": self.refill,
"type": self.arena_type,
"goal": self.match_goal,
"name": self.name
}
return data
def load(self, data):
self.explosion_damage = None if str(data["explosion"]) == "None" else float(data["explosion"])
self.player_limit = None if str(data["players"]) == "None" else int(data["players"])
self.refill = None if str(data["refill"]) == "None" else int(data["refill"])
self.arena_type = str(data["type"])
self.match_goal = None if str(data["goal"]) == "None" else int(data["goal"])
self.corner1 = Coords(None).load(data["corners"][0]) if not data["corners"][0] == None else None
self.corner2 = Coords(None).load(data["corners"][1]) if not data["corners"][1] == None else None
self.tpp = Coords(None).load(data["corners"][2]) if not data["corners"][2] == None else None
self.bnn = Coords(None).load(data["corners"][3]) if not data["corners"][3] == None else None
for subdata in data["spawns"]:
self.spawn_location.append(NamedCoords(None, None).load(subdata))
for subdata in data["respawns"]:
self.respawn_location.append(NamedCoords(None, None).load(subdata))
for subdata in data["signs"]:
self.sign_location.append(NamedCoords(None, None).load(subdata))
for subdata in data["clicks"]:
self.sign_click.append(NamedCoords(None, None).load(subdata))
self.name = data["name"]
return self
#coord = an instance of Coords class, adds a name to it.
class NamedCoords(object):
def __init__(self, name, coord):
self.name = name
self.coord = coord
def get_name(self):
return self.name
def get_location(self):
return self.coord
def get_data(self):
coords = self.coord.get_location()
data = {
"x": coords.x,
"y": coords.y,
"z": coords.z,
"yaw": coords.yaw,
"pitch": coords.pitch,
"world": coords.getWorld().getName(),
"name": self.name
}
return data
def load(self, data):
self.name = str(data["name"])
self.coord = Coords(None).load(data)
return self
class Coords(object):
def __init__(self, world = None, x = None, y = None, z = None, yaw = None, pitch = None):
if world == None:
self.world = None
self.x = None
self.y = None
self.z = None
self.yaw = None
self.pitch = None
return
if not isinstance(world, Location):
self.x = x
self.y = y
self.z = z
self.yaw = yaw
self.pitch = pitch
self.world = world.getName()
else:
location = world
self.x = location.x
self.y = location.y
self.z = location.z
self.yaw = location.yaw
self.pitch = location.pitch
self.world = location.getWorld().getName()
def get_location(self):
return Location(server.getWorld(str(self.world)), float(self.x), float(self.y), float(self.z), int(self.yaw), int(self.pitch))
def set_location(self, location):
self.x = location.x
self.y = location.y
self.z = location.z
self.yaw = location.yaw
self.pitch = location.pitch
self.world = location.getWorld().getName()
def get_data(self):
data = {
"x": self.x,
"y": self.y,
"z": self.z,
"yaw": self.yaw,
"pitch": self.pitch,
"world": self.world
}
return data
def load(self, data):
self.x = float(data["x"])
self.y = float(data["y"])
self.z = float(data["z"])
self.yaw = int(data["yaw"])
self.pitch = int(data["pitch"])
self.world = str(data["world"])
return self
class Queue(object):
def __init__(self):
self.queue = []
#Appends to queue
def put(self,args):
self.queue.append(args)
#Returns the first item in the queue and removes it
def get(self):
if len(self.queue) > 0:
return self.queue.pop(0)
else:
return False
#Returns the queue's list object
def read(self):
return self.queue
#Removes the value args from the queue
def remove(self,args):
self.queue.remove(args)
#Check if queue contains player
def contains(self, player):
if player in self.queue:
return True
return False
#Clear the queue
def clear(self):
self.queue = []
##############################################################################################
# Initialization
##############################################################################################
def save_snowbrawl():
out = []
for arena in arenas:
out.append(arena.get_data())
save_json_file(file, out)
def load_snowbrawl():
out = []
buffer = open_json_file(file, [])
for data in buffer:
out.append(Arena(None).load(data))
return out
arenas = load_snowbrawl()
##############################################################################################
# Threads
##############################################################################################
class timings_runnable(Runnable):
def __init__(self, arena):
self.arena = arena
def run(self):
self.arena.end_match()
#timings thread to end arenas if their type is time
def timings():
while True:
for arena in arenas:
if arena.is_running():
if arena.arena_type == "time":
current_time = time.time()
start_time = arena.start_time
if arena.start_time + arena.match_goal < current_time:
timing = timings_runnable(arena)
server.getScheduler().runTask(server.getPluginManager().getPlugin("RedstonerUtils"), timing)
time.sleep(0.1)
timingsThread = threading.Thread(target = timings)
timingsThread.daemon = True #Thread dies if main thread dies
timingsThread.start()
##############################################################################################
# Events
##############################################################################################
@hook.event("player.PlayerMoveEvent", "low")
def onMove(event):
if event.getPlayer().getWorld().getName() != "minigames":
return
player = event.getPlayer()
for arena in arenas:
if arena.in_players(player):
loc = player.getLocation()
block = player.getWorld().getBlockAt(int(loc.x), int(loc.y) - 1, int(loc.z))
if block != None:
material = block.getType()
if material == Material.SPONGE:
player.addPotionEffect(PotionEffect(PotionEffectType.JUMP, 60, 0))
elif material == Material.GLASS or material == Material.STAINED_GLASS:
player.addPotionEffect(PotionEffect(PotionEffectType.SPEED, 60, 0))
elif material == Material.OBSIDIAN:
player.addPotionEffect(PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 300, 0))
break
@hook.event("entity.PlayerDeathEvent", "high")
def onDeath(event):
if event.getEntity().getWorld().getName() != "minigames":
return
if not isinstance(event.getEntity(), bukkit.entity.Player):
return
for arena in arenas:
if arena.in_players(event.getEntity()):
arena.player_stats[event.getEntity().getName() + "_deaths"] += 1
if arena.check_deaths():
arena.end_match()
break
@hook.event("player.PlayerRespawnEvent", "high")
def onRespawn(event):
if event.getPlayer().getWorld().getName() != "minigames":
return
player = event.getPlayer()
for arena in arenas:
if arena.in_players(player):
event.setRespawnLocation(arena.get_respawn().get_location().get_location())
break
@hook.event("entity.ProjectileHitEvent", "high")
def onHit(event):
if event.getEntity().getWorld().getName() != "minigames":
return
if event.getEntity().getName() != "Snowball":
return
location = event.getEntity().getLocation()
for arena in arenas:
if arena.in_arena(location):
event.getEntity().getWorld().createExplosion(location.x, location.y, location.z, float(arena.get_explosion_damage()), False, False)
break
@hook.event("player.PlayerInteractEvent", "high")
def onClick(event):
if event.getPlayer().getWorld().getName() != "minigames":
return
if str(event.getAction()) != "RIGHT_CLICK_BLOCK":
return
block = event.getClickedBlock().getState()
if event.getClickedBlock().getType() == Material.SNOW_BLOCK:
for arena in arenas:
if arena.in_players(event.getPlayer()):
inv = event.getPlayer().getInventory()
inv.remove(Material.SNOW_BALL)
inv.setItemInHand(ItemStack(Material.SNOW_BALL, arena.get_refill()))
event.getPlayer().updateInventory()
break
elif isinstance(block, bukkit.block.Sign):
line = str(block.getLine(1))
if not event.getPlayer().hasPermission(join_perm):
msg(event.getPlayer(), "&a-&e You don't have permission to join snowbrawl matches")
return
#go through arenas, if name matches line then add player to it
for arena in arenas:
if line == arena.get_name():
for sign in arena.get_click_signs():
sign_loc = sign.get_location().get_location()
loc = block.getLocation()
if sign_loc.getWorld().getName() == loc.getWorld().getName() and sign_loc.x == loc.x and sign_loc.y == loc.y and sign_loc.z == loc.z:
if arena.add_player(event.getPlayer()):
msg(event.getPlayer(),"&a- &eYou have been added to the queue")
else:
msg(event.getPlayer(),"&a- &eYou are already in the queue")
break
return
@hook.event("player.PlayerQuitEvent", "normal")
def on_quit(event):
#remove the player from the queue
player = event.getPlayer().getName()
for arena in arenas:
if arena.in_queue(player):
arena.remove_player(player)
##############################################################################################
# Command handling
##############################################################################################
def create_arena(sender, args):
if len(args) == 0:
msg(sender, "&c/sb %s <name>" % create_command)
return
arena = Arena(args[0])
arenas.append(arena)
msg(sender, "&a-&e Arena %s created" % args[0])
def list_arenas(sender):
if len(arenas) == 0:
msg(sender, "&a-&e There are currently no arenas")
return
for arena in arenas:
msg(sender, "&a-&e %s" % arena.get_name())
def arena_info(sender, args):
if len(args) == 0:
msg(sender, "&a-&e /sb info <name>")
return
if len(arenas) == 0:
msg(sender, "&a-&e There are currently no arenas")
return
for arena in arenas:
if arena.get_name() == args[0]:
msg(sender, "&a-&e %s" % arena.get_name())
#msg(sender, "&ePlayers:&6 " + "&e,&6 ".join(arena.get_queue_contents()))
spawn_list = []
for spawn in arena.get_location("spawn"):
spawn_list.append(spawn.get_name())
msg(sender, "&eSpawns:&6 " + "&e,&6 ".join(spawn_list))
respawn_list = []
for respawn in arena.get_location("respawn"):
respawn_list.append(respawn.get_name())
msg(sender, "&eRespawns:&6 " + "&e,&6 ".join(respawn_list))
sign_list = []
for sign in arena.get_location("sign"):
sign_list.append(sign.get_name())
msg(sender, "&eSigns:&6 " + "&e,&6 ".join(sign_list))
break
def quit_match(sender):
for arena in arenas:
if arena.in_queue(sender):
arena.remove_player(sender)
msg(sender, "&a-&e Quit arena")
return
msg(sender, "&a-&e You're not in a queue")
def print_help(sender):
msg(sender, "&a-&e Alias: &6/sb")
if sender.hasPermission(teleport_perm):
msg(sender, "&a-&e /sb <name> Teleport to an arena")
if sender.hasPermission(quit_perm):
msg(sender, "&a-&e /sb %s Quit a queue" % quit_command)
if sender.hasPermission(list_perm):
msg(sender, "&a-&e /sb %s List all existing arenas" % list_command)
if sender.hasPermission(create_perm):
msg(sender, "&a-&e /sb %s Create an arena" % create_command)
if sender.hasPermission(info_perm):
msg(sender, "&a-&e /sb %s Show info about an arena" % info_command)
if sender.hasPermission(modify_perm):
msg(sender, "&a-&e /sb %s Deletes an arena" % del_command)
msg(sender, "&a-&e /sb %s Sets a teleport for an arena to a sign" % set_command)
msg(sender, "&a-&e /sb %s Renames an arena" % name_command)
msg(sender, "&a-&e /sb %s Sets the locations for an arena" % pos_command)
msg(sender, "&a-&e /sb %s Modifies the arena" % modify_command)
msg(sender, "&a-&e Modify Aliases: &6/sbm&e,&6 /sb %s" % modify_command_alias)
def set_location(sender, args):
if len(args) < 3:
msg(sender, "&c/sb pos <arena name> respawn/spawn/sign set/add/del <name>")
msg(sender, "&c/sb pos <arena name> bounds corner1/corner2")
return
if "bounds" not in args:
if len(args) < 4:
msg(sender, "&c/sb pos <arena name> respawn/spawn/sign set/add/del <name>")
msg(sender, "&c/sb pos <arena name> bounds corner1/corner2")
return
if len(arenas) == 0:
msg(sender, "&a-&e There are currently no arenas")
return
for arena in arenas:
if arena.get_name() == args[0]:
if args[1] == "respawn":
set_location_of_type(sender, args[2:], "respawn", arena)
elif args[1] == "spawn":
set_location_of_type(sender, args[2:], "spawn", arena)
elif args[1] == "sign":
set_location_of_type(sender, args[2:], "sign", arena)
elif args[1] == "bounds":
set_location_of_type(sender, args[2:], "bounds", arena)
break
def set_location_of_type(sender, args, type, arena):
if len(args) == 0:
msg(sender, "&c/sb pos <arena name> respawn/spawn/sign set/add/del <name>")
msg(sender, "&c/sb pos <arena name> bounds corner1/corner2")
return
location = sender.getLocation()
if args[0] == "set":
arena.change_location(args[1], location, type)
msg(sender, "&a-&e Location of name %s and type %s changed to your current location" % (args[1], type))
elif args[0] == "add":
arena.add_location(args[1], location, type)
msg(sender, "&a-&e Location of name %s and type %s created at your current location" % (args[1], type))
elif args[0] == "del":
arena.delete_location(args[1], type)
msg(sender, "&a-&e Location of name %s deleted" % args[1])
elif args[0] == "corner1":
arena.set_corner(sender, "1")
elif args[0] == "corner2":
arena.set_corner(sender, "2")
def rename_arena(sender, args):
if len(args) < 2:
msg(sender, "&c/sb name <name> <new name>")
return
for arena in arenas:
if arena.get_name() == args[0]:
arena.set_name(args[1])
msg(sender, "&a-&e Arena %s renamed to %s" % (args[0], args[1]))
return
msg(sender, "&a-&e Arena with this name doesn't exist")
def delete_arena(sender, args):
if len(args) == 0:
msg(sender, "&c/sb del <name>")
return
for arena in arenas:
if arena.get_name() == args[0]:
arenas.remove(arena)
msg(sender, "&a-&e Arena %s deleted" % arena.get_name())
return
msg(sender, "&a-&e Arena with this name doesn't exist")
def teleport_to_arena(sender, name, id):
try:
int(id)
except ValueError:
msg(sender, "&c/sb <name> <id of teleport>")
return
for arena in arenas:
if arena.get_name() == name:
i = 0
if int(id) > len(arena.get_tp_signs()):
msg(sender, "&cGiven tp id is out of range")
return
for sign in arena.get_tp_signs():
i += 1
if i == int(id):
loc = sign.get_location().get_location()
safetp(sender, loc.getWorld(), loc.x, loc.y, loc.z, loc.yaw, loc.pitch)
break
msg(sender, "&a-&e Teleporting to arena %s" % name)
return
msg(sender, "&a-&e Arena with this name doesn't exist")
def modify_arena(sender, args):
if len(args) < 3:
msg(sender, "&c/sb modify <arena name> limit/mode/players/explosion/refill <amount/mode (death/time)>")
return
for arena in arenas:
if arena.get_name() == args[0]:
if args[1] == "limit":
try:
int(args[2])
except ValueError:
msg(sender, "&cLast parameter has to be a number")
return
arena.set_end_goal(int(args[2]))
msg(sender, "&a-&e Set time/death limit to:&6 %s" % int(args[2]))
elif args[1] == "mode":
if args[2] == "time" or args[2] == "death":
arena.set_type(args[2])
msg(sender, "&a-&e Set mode to:&6 %s" % args[2])
else:
msg(sender, "&cInvalid mode (time, death)")
elif args[1] == "players":
try:
int(args[2])
except ValueError:
msg(sender, "&cLast parameter has to be a number")
return
arena.set_player_limit(int(args[2]))
msg(sender, "&a-&e Set player limit to:&6 %s" % int(args[2]))
elif args[1] == "explosion":
try:
float(args[2])
except ValueError:
msg(sender, "&cLast parameter has to be a number")
return
arena.set_explosion_damage(float(args[2]))
msg(sender, "&a-&e Set explosion power to:&6 %s" % float(args[2]))
elif args[1] == "refill":
try:
int(args[2])
except ValueError:
msg(sender, "&cLast parameter has to be a number")
return
arena.set_refill(int(args[2]))
msg(sender, "&a-&e Set snowball refill to:&6 %s" % int(args[2]))
return
msg(sender, "&a-&e Arena with this name doesn't exist")
def set_arena_sign(sender, args):
if len(args) < 3:
msg(sender, "&c/sb set <arena name> add/del <name>")
return
for arena in arenas:
if arena.get_name() == args[0]:
if args[1] == "add":
arena.add_sign(sender, args[2])
elif args[1] == "del":
arena.del_sign(sender, args[2])
@hook.command("snowbrawl")
def on_snowbrawl_command(sender, command, label, args):
if len(args) == 0:
#print help
plugin_header(sender, "Snowbrawl")
print_help(sender)
return True
elif args[0] == list_command:
if sender.hasPermission(list_perm):
#print the list of arenas
list_arenas(sender)
else:
noperm(sender)
return True
elif args[0] == del_command:
if sender.hasPermission(modify_perm):
#delete an arena
delete_arena(sender, args[1:])
save_snowbrawl()
else:
noperm(sender)
return True
elif args[0] == info_command:
if sender.hasPermission(info_perm):
#print info about an arena
arena_info(sender, args[1:])
else:
noperm(sender)
return True
elif args[0] == create_command:
if sender.hasPermission(create_perm):
#create an arena
create_arena(sender, args[1:])
save_snowbrawl()
else:
noperm(sender)
return True
elif args[0] == pos_command:
if sender.hasPermission(modify_perm):
#set arena spawn/respawn/sign tp locations
set_location(sender, args[1:])
save_snowbrawl()
else:
noperm(sender)
return True
elif args[0] == name_command:
if sender.hasPermission(modify_perm):
#rename an arena
rename_arena(sender, args[1:])
save_snowbrawl()
else:
noperm(sender)
return True
elif args[0] == set_command:
if sender.hasPermission(modify_perm):
#set an arena tp sign
set_arena_sign(sender, args[1:])
save_snowbrawl()
else:
noperm(sender)
return True
elif args[0] == modify_command or args[0] == modify_command_alias:
if sender.hasPermission(modify_perm):
#modify the arena
modify_arena(sender, args[1:])
save_snowbrawl()
else:
noperm(sender)
return True
elif args[0] == quit_command:
if sender.hasPermission(quit_perm):
#quit match
quit_match(sender)
else:
noperm(sender)
return True
else:
if sender.hasPermission(teleport_perm):
#try to tp to an arena
if len(args) > 1:
teleport_to_arena(sender, args[0], args[1])
else:
teleport_to_arena(sender, args[0], 1)
else:
noperm(sender)
return True
+37 -43
View File
@@ -1,9 +1,3 @@
"""
Code that was used once to create this awesome screenshot
- https://i.imgur.com/v4wg5kl.png
- https://i.imgur.com/tIZ3jmC.png
- https://www.reddit.com/r/Minecraft/comments/28le52/screenshot_of_all_players_that_joined_my_server/
"""
import net.minecraft.server.v1_7_R1.EntityPlayer as EntityPlayer import net.minecraft.server.v1_7_R1.EntityPlayer as EntityPlayer
import net.minecraft.server.v1_7_R1.PacketPlayOutNamedEntitySpawn as PacketPlayOutNamedEntitySpawn import net.minecraft.server.v1_7_R1.PacketPlayOutNamedEntitySpawn as PacketPlayOutNamedEntitySpawn
import net.minecraft.server.v1_7_R1.PlayerInteractManager as PlayerInteractManager import net.minecraft.server.v1_7_R1.PlayerInteractManager as PlayerInteractManager
@@ -24,45 +18,45 @@ upmul = 0.95 # multiplicate with goup each row
def spawn(dispname, sender, x, y, z): def spawn(dispname, sender, x, y, z):
""" """
Sends the actual player to sender Sends the actual player to sender
""" """
server = bukkit.getServer().getServer() server = bukkit.getServer().getServer()
world = server.getWorldServer(0) # main world world = server.getWorldServer(0) # main world
profile = GameProfile(dispname, dispname) # set player details profile = GameProfile(dispname, dispname) # set player details
manager = PlayerInteractManager(world) manager = PlayerInteractManager(world)
entity = EntityPlayer(server, world, profile, manager) # create Player's entity entity = EntityPlayer(server, world, profile, manager) # create Player's entity
entity.setPosition(x, y, z) entity.setPosition(x, y, z)
packet = PacketPlayOutNamedEntitySpawn(entity) # create packet for entity spawn packet = PacketPlayOutNamedEntitySpawn(entity) # create packet for entity spawn
sender.getHandle().playerConnection.sendPacket(packet) # send packet sender.getHandle().playerConnection.sendPacket(packet) # send packet
@hook.command("spawnplayer") @hook.command("spawnplayer")
def on_spawnplayer_command(sender, command, label, args): def on_spawnplayer_command(sender, args):
global amount, row, ground, goup global amount, row, ground, goup
# X and Z position # X and Z position
xpos = sender.getLocation().add(-float(row-1 * shift + (amount * margin) / 2), 0, 0).getX() xpos = sender.getLocation().add(-float(row-1 * shift + (amount * margin) / 2), 0, 0).getX()
row = sender.getLocation().add(0, 0, -row).getZ() row = sender.getLocation().add(0, 0, -row).getZ()
count = 0 count = 0
stop = False stop = False
while not stop: while not stop:
for i in range(amount): for i in range(amount):
player = players[count] player = players[count]
x = int(xpos + i*margin) x = int(xpos + i*margin)
spawn(player, sender, x, ground, row) spawn(player, sender, x, ground, row)
print(player, x, ground, row) print(player, x, ground, row)
count += 1 count += 1
if count >= len(players): if count >= len(players):
stop = True stop = True
print "breaking" print "breaking"
break break
print("next row") print("next row")
row -= 1 # next row (-z) row -= 1 # next row (-z)
xpos -= shift # shift left xpos -= shift # shift left
amount += int(shift*margin*2) # add players left and right amount += int(shift*margin*2) # add players left and right
if abs(row) % int(goup) == 0: if abs(row) % int(goup) == 0:
goup *= upmul goup *= upmul
ground += 1 ground += 1
print "Going up by 1: %s" % ground print "Going up by 1: %s" % ground
-112
View File
@@ -1,112 +0,0 @@
from helpers import *
from secrets import *
import mysqlhack
from com.ziclix.python.sql import zxJDBC
"""
WORK IN PROGRESS
"""
#-----------------------Config--------------------------
config_file = "website-roles"
ranks = {
"member" : 3,
"builder" : 7,
"trusted" : 8,
"helper" : 9,
"trainingmod" : 10,
"mod" : 4,
"admin" : 5
}
ranks = open_json_file(config_file, ranks)
def save_ranks():
save_json_file(config_file, ranks)
#-----------------------Event---------------------------
@hook.event("player.PlayerJoinEvent", "normal")
def on_player_join(event):
user = event.getPlayer()
uuid = uid(player).replace("-", "")
sql_instruction
def callback_thing(role, args):
if role in [1, 2, 6]: #Disabled/Banned/Superadmin
return
if role != None:
for rank in ranks:
if user.hasPermission("group." + rank):
if role != ranks[rank]:
set_role(uuid, ranks[rank])
elif user.hasPlayedBefore():
msg(user, "&cYou haven't registed yet! Make sure to do so on redstoner.com")
def get_role(uuid):
results = execute_query("SELECT `role_id` FROM users WHERE `uuid` = ? LIMIT 1;", uuid)
return results[0][0]
# Returns a table with 1 row (LIMIT 1) and 1 column (SELECT `role_id`), so we're looking for the first row of the first column.
def set_role(uuid, role_id):
execute_update("UPDATE users SET `role_id` = ? WHERE `uuid` = ?;", (role_id, uuid,))
# %d is like %s for integers (unlogically, you'd expect something like %i), though %s also works here.
def execute_query(query, uuid):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute(query, (uuid,))
results = curs.fetchall()
curs.close()
conn.close()
return results
def execute_update(update, uuid):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
curs.execute(update, (uuid,))
conn.commit()
curs.close()
conn.close()
def get_role(uuid):
sql_instruction()
#--------------------------------Queries / Updates----------------------------
def sql_instruction(instruction, args, fetch = True, callback_func = ignored_func, callback_args = tuple()):
thread = threading.Thread(target = curs_instruction, args = (instruction_executor, instruction, fetch, callback_func, callback_args))
thread.start()
def curs_instruction(func, instruction, fetch, callback_func, callback_args):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.getCursor()
if fetch:
returned = func(curs, instruction, fetch)
curs.close()
conn.close()
callback_func(returned, callback_args)
else:
func(curs, instruction, fetch)
conn.commit()
curs.close()
conn.close()
def instruction_executor(curs, instruction, fetch):
curs.execute(instruction)
return curs.fetchall() if fetch else None
def ignored_func(*args):
pass
-78
View File
@@ -1,78 +0,0 @@
from helpers import *
add_perm = "utils.tag.add"
del_perm = "utils.tag.del"
check_perm = "utils.tag.check"
data = open_json_file("tag", {})
@hook.command("tag")
def command(sender, command, label, args):
if len(args) > 0:
if str(args[0]) == "add":
if sender.hasPermission(add_perm):
if len(args) > 2:
add(sender, args[1:])
else:
msg(sender, "&a-&c Usage: /tag add <name> <reason>")
else:
noperm(sender)
elif str(args[0]) == "check":
if sender.hasPermission(check_perm):
if len(args) == 2:
check(sender, args[1:])
else:
msg(sender, "&a-&c Usage: /tag check <name>")
else:
noperm(sender)
elif str(args[0]) == "del":
if sender.hasPermission(del_perm):
if len(args) == 3:
delete(sender, args[1:])
else:
msg(sender, "&a-&c Usage: /tag del <id>")
else:
msg(sender, "&a-&c Unknown subcommand! (add, check, del)")
else:
msg(sender, "&a&c Usage: /tag add/check/del")
return True
def delete(sender, args):
player = server.getOfflinePlayer(args[0])
uuid = uid(player)
try:
if data[uuid] == None:
pass
except:
msg(sender, "&a-&e There are no notes about this player")
return
if int(args[1]) - 1 >= len(data[uuid]):
msg(sender, "&a-&c Id of note is out of range")
return
del (data[uuid])[int(args[1]) - 1]
save_json_file("tag", data)
msg(sender, "&a-&e Deleted note at %s" % args[1])
def add(sender, args):
player = server.getOfflinePlayer(args[0])
uuid = uid(player)
try:
if data[uuid] == None:
pass
except:
data[uuid] = []
data[uuid].append(" ".join(args[1:]))
msg(sender, "&a-&e Note added")
save_json_file("tag", data)
def check(sender, args):
player = server.getOfflinePlayer(args[0])
uuid = uid(player)
try:
num = 0
for tag in data[uuid]:
num += 1
msg(sender, "&a-&e %s: %s" % (str(num), str(tag)))
except:
msg(sender, "&a-&e There are no notes about this player")
+94 -97
View File
@@ -1,7 +1,4 @@
#pylint: disable = F0401 #pylint: disable = F0401
"""
A plugin that automatically tiles (stacks) blocks inside a selected region in configurable directions.
"""
import org.bukkit.event.block.BlockPlaceEvent as BlockPlaceEvent import org.bukkit.event.block.BlockPlaceEvent as BlockPlaceEvent
import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
import org.bukkit.event.player.PlayerInteractEvent as PlayerInteractEvent import org.bukkit.event.player.PlayerInteractEvent as PlayerInteractEvent
@@ -12,13 +9,13 @@ from helpers import *
tilehelpers = open_json_file("tilehelpers", []) tilehelpers = open_json_file("tilehelpers", [])
dirmap = { dirmap = {
# [x, y, z] # [x, y, z]
"n": [0, 0, -1], "n": [0, 0, -1],
"e": [+1, 0, 0], "e": [+1, 0, 0],
"s": [0, 0, +1], "s": [0, 0, +1],
"w": [-1, 0, 0], "w": [-1, 0, 0],
"u": [0, +1, 0], "u": [0, +1, 0],
"d": [0, -1, 0] "d": [0, -1, 0]
} }
# FIXME: disallow multiple regions by single person. # FIXME: disallow multiple regions by single person.
@@ -27,111 +24,111 @@ dirmap = {
@hook.event("block.BlockPlaceEvent", "low") @hook.event("block.BlockPlaceEvent", "low")
def on_place_block(event): def on_place_block(event):
if not event.isCancelled(): if not event.isCancelled():
player = event.getPlayer() player = event.getPlayer()
block = event.getBlockPlaced() block = event.getBlockPlaced()
for th in tilehelpers: for th in tilehelpers:
area = th.get("area") area = th.get("area")
if th.get("owner") == uid(player) and str(block.getWorld().getUID()) == th.get("world") and block.getX() in range(area[0][0], area[0][1]+1) and block.getY() in range(area[1][0], area[1][1]+1) and block.getZ() in range(area[2][0], area[2][1]+1) and event.canBuild(): if th.get("owner") == uid(player) and str(block.getWorld().getUID()) == th.get("world") and block.getX() in range(area[0][0], area[0][1]+1) and block.getY() in range(area[1][0], area[1][1]+1) and block.getZ() in range(area[2][0], area[2][1]+1) and event.canBuild():
# stack block in directions # stack block in directions
for direction in th.get("directions"): for direction in th.get("directions"):
directions = dirmap[direction] directions = dirmap[direction]
size = [ size = [
1 + abs(area[0][1] - area[0][0]), 1 + abs(area[0][1] - area[0][0]),
1 + abs(area[1][1] - area[1][0]), 1 + abs(area[1][1] - area[1][0]),
1 + abs(area[2][1] - area[2][0]) 1 + abs(area[2][1] - area[2][0])
] ]
against = event.getBlockAgainst() against = event.getBlockAgainst()
newblock = block.getWorld().getBlockAt( newblock = block.getWorld().getBlockAt(
block.getX() + size[0] * directions[0], block.getX() + size[0] * directions[0],
block.getY() + size[1] * directions[1], block.getY() + size[1] * directions[1],
block.getZ() + size[2] * directions[2] block.getZ() + size[2] * directions[2]
) )
newagainst = against.getWorld().getBlockAt( newagainst = against.getWorld().getBlockAt(
against.getX() + size[0] * directions[0], against.getX() + size[0] * directions[0],
against.getY() + size[1] * directions[1], against.getY() + size[1] * directions[1],
against.getZ() + size[2] * directions[2] against.getZ() + size[2] * directions[2]
) )
newstate = newblock.getState() newstate = newblock.getState()
newstate.setType(block.getType()) newstate.setType(block.getType())
newstate.setData(block.getState().getData()) newstate.setData(block.getState().getData())
event = BlockPlaceEvent(newstate.getBlock(), newblock.getState(), newagainst, event.getItemInHand(), player, event.canBuild()) event = BlockPlaceEvent(newstate.getBlock(), newblock.getState(), newagainst, event.getItemInHand(), player, event.canBuild())
server.getPluginManager().callEvent(event) server.getPluginManager().callEvent(event)
if not event.isCancelled(): if not event.isCancelled():
newblock.setType(block.getType()) newblock.setType(block.getType())
newblock.setData(block.getData()) newblock.setData(block.getData())
@hook.event("block.BlockBreakEvent", "low") @hook.event("block.BlockBreakEvent", "low")
def on_break_block(event): def on_break_block(event):
if not event.isCancelled(): if not event.isCancelled():
player = event.getPlayer() player = event.getPlayer()
block = event.getBlock() block = event.getBlock()
for th in tilehelpers: for th in tilehelpers:
area = th.get("area") area = th.get("area")
if th.get("owner") == uid(player) and str(block.getWorld().getUID()) == th.get("world") and block.getX() in range(area[0][0], area[0][1]+1) and block.getY() in range(area[1][0], area[1][1]+1) and block.getZ() in range(area[2][0], area[2][1]+1): if th.get("owner") == uid(player) and str(block.getWorld().getUID()) == th.get("world") and block.getX() in range(area[0][0], area[0][1]+1) and block.getY() in range(area[1][0], area[1][1]+1) and block.getZ() in range(area[2][0], area[2][1]+1):
# stack block in directions # stack block in directions
for direction in th.get("directions"): for direction in th.get("directions"):
directions = dirmap[direction] directions = dirmap[direction]
size = [ size = [
1 + abs(area[0][1] - area[0][0]), 1 + abs(area[0][1] - area[0][0]),
1 + abs(area[1][1] - area[1][0]), 1 + abs(area[1][1] - area[1][0]),
1 + abs(area[2][1] - area[2][0]) 1 + abs(area[2][1] - area[2][0])
] ]
newblock = block.getWorld().getBlockAt( newblock = block.getWorld().getBlockAt(
block.getX() + size[0] * directions[0], block.getX() + size[0] * directions[0],
block.getY() + size[1] * directions[1], block.getY() + size[1] * directions[1],
block.getZ() + size[2] * directions[2] block.getZ() + size[2] * directions[2]
) )
event = BlockBreakEvent(newblock, player) event = BlockBreakEvent(newblock, player)
server.getPluginManager().callEvent(event) server.getPluginManager().callEvent(event)
if not event.isCancelled(): if not event.isCancelled():
newblock.setTypeId(0) newblock.setTypeId(0)
@hook.event("player.PlayerInteractEvent", "low") @hook.event("player.PlayerInteractEvent", "low")
def on_block_interact(event): def on_block_interact(event):
action = event.getAction() action = event.getAction()
if not event.isCancelled() and str(action) == "RIGHT_CLICK_BLOCK": if not event.isCancelled() and str(action) == "RIGHT_CLICK_BLOCK":
player = event.getPlayer() player = event.getPlayer()
block = event.getClickedBlock() block = event.getClickedBlock()
for th in tilehelpers: for th in tilehelpers:
area = th.get("area") area = th.get("area")
if th.get("owner") == uid(player) and str(block.getWorld().getUID()) == th.get("world") and block.getX() in range(area[0][0], area[0][1]+1) and block.getY() in range(area[1][0], area[1][1]+1) and block.getZ() in range(area[2][0], area[2][1]+1): if th.get("owner") == uid(player) and str(block.getWorld().getUID()) == th.get("world") and block.getX() in range(area[0][0], area[0][1]+1) and block.getY() in range(area[1][0], area[1][1]+1) and block.getZ() in range(area[2][0], area[2][1]+1):
# stack block in directions # stack block in directions
for direction in th.get("directions"): for direction in th.get("directions"):
directions = dirmap[direction] directions = dirmap[direction]
size = [ size = [
1 + abs(area[0][1] - area[0][0]), 1 + abs(area[0][1] - area[0][0]),
1 + abs(area[1][1] - area[1][0]), 1 + abs(area[1][1] - area[1][0]),
1 + abs(area[2][1] - area[2][0]) 1 + abs(area[2][1] - area[2][0])
] ]
newblock = block.getWorld().getBlockAt( newblock = block.getWorld().getBlockAt(
block.getX() + size[0] * directions[0], block.getX() + size[0] * directions[0],
block.getY() + size[1] * directions[1], block.getY() + size[1] * directions[1],
block.getZ() + size[2] * directions[2] block.getZ() + size[2] * directions[2]
) )
event = PlayerInteractEvent(event.getPlayer(), action, event.getItem(), newblock, event.getBlockFace()) event = PlayerInteractEvent(event.getPlayer(), action, event.getItem(), newblock, event.getBlockFace())
server.getPluginManager().callEvent(event) server.getPluginManager().callEvent(event)
if not event.isCancelled(): if not event.isCancelled():
# FIXME: do not use bukkit API calls outside main thread # FIXME: do not use bukkit API calls outside main thread
thread.start_new_thread(update_block, (block, newblock)) thread.start_new_thread(update_block, (block, newblock))
def update_block(block, newblock): def update_block(block, newblock):
try: # we're in a thread, the universe may hace collapsed in another thread try: # we're in a thread, the universe may hace collapsed in another thread
sleep(0.2) sleep(0.2)
newblock.setType(block.getType()) newblock.setType(block.getType())
newblock.setData(block.getData()) newblock.setData(block.getData())
except Exception, e: except Exception, e:
error("Failed to update %s block in %s at %s,%s,%s: '%s'" % (str(block.getType()), block.getWorld().getName(), block.getX(), block.getY(), block.getZ(), e)) error("Failed to update %s block in %s at %s,%s,%s: '%s'" % (str(block.getType()), block.getWorld().getName(), block.getX(), block.getY(), block.getZ(), e))
+4
View File
@@ -0,0 +1,4 @@
import glob
tools = []
for module_name in glob.glob("plugins/redstoner-utils.py.dir/toolbox/*.py"):
tools.append(__import__(module_name))
+42
View File
@@ -0,0 +1,42 @@
from helpers import *
gamemode_permission = {"self":"gamemode.self","other":"gamemode.other"}
# Helping functions
def setGamemode(sender, gmstring):
gmstring = gmstring.lower()
if is_player(sender):
if gmstring == "c" || gmstring == "creative" || gmstring == "1":
sender.setGameMode(GameMode.CREATIVE)
elif gmstring == "s" || gmstring == "survival" || gmstring == "0":
sender.setGameMode(GameMode.SURVIVAL)
elif gmstring == "a" || gmstring == "adventure" || gmstring == "2":
sender.setGameMode(GameMode.ADVENTURE)
else
msg(sender, "&c%s is no known gamemode (survival/creative/adventure)")
else
msg(sender, "&cYou have to be a valid player to perform this command. Try /gamemode <player> <gamemode>")
# /toolbox
@hook.command("toolbox", desc="The basic command of Toolbox")
def toolbox_command(sender, args):
msg(sender, "&6Toolbox&f is a command library written for Redstoner.com")
# /gamemode
@hook.command("gamemode", aliases=["gm"], desc="Change a player's gamemode")
def toolbox_gamemode_command(sender, args):
param1 = args[0].lower() if len(args)>0 else None
param2 = args[1] if len(args)>1 else None
if len(args) == 1:
if sender.hasPermission(gamemode_permission["self"]) || sender.hasPermission(gamemode_permission["other"]):
setGameMode(sender, param1)
else
noperm(sender)
elif len(args) == 2:
if sender.hasPermission(gamemode_permission["other"]):
if server.getPlayer(param) != None:
setGameMode(server.getPlayer(param), param2)
else
msg(sender, "&cThere's no online player called "+param)
-121
View File
@@ -1,121 +0,0 @@
from helpers import *
from basecommands import simplecommand
from basecommands import Validate
vanished = []
def is_authorized(player):
return player.hasPermission("utils.vanish")
def is_vanished(player):
return uid(player) in vanished
#this can be used to silently set the vanished state of a player
def set_state(player, state):
if state == is_vanished(player):
return
if state:
enable_vanish(player)
else:
disable_vanish(player)
def enable_vanish(target):
vanished.append(uid(target))
for player in list(server.getOnlinePlayers()):
if not is_authorized(player):
player.hidePlayer(target)
def disable_vanish(target):
vanished.remove(uid(target))
for player in list(server.getOnlinePlayers()):
player.showPlayer(target)
@simplecommand("vanish",
aliases = ["v"],
usage = "[on/off]",
description = "Toggles vanish mode, hiding you and your online status \nfrom other players.",
senderLimit = 0,
amin = 0,
amax = 1,
helpNoargs = False,
helpSubcmd = True
)
def vanish_command(sender, command, label, args):
try:
current_state = is_vanished(sender)
new_state = not current_state
if len(args) == 1:
arg = args[0].lower()
if arg == "on":
new_state = True
elif arg == "off":
new_state = False
if current_state == new_state:
return "&cYou were %s vanished!" % ("already" if current_state else "not yet")
set_state(sender, new_state)
return "&a%s vanish mode!" % ("Enabled" if new_state else "Disabled")
except:
error(trace())
@hook.event("player.PlayerJoinEvent")
def on_player_join(event):
player = event.getPlayer()
if not is_authorized(player):
for uuid in vanished:
player.hidePlayer(retrieve_player(uuid))
elif is_vanished(player):
msg(player, "&cKeep in mind that you are still vanished! Use /vanish to disable.")
@hook.event("player.PlayerQuitEvent")
def on_player_quit(event):
player = event.getPlayer()
if not is_authorized(player):
for uuid in vanished:
player.showPlayer(retrieve_player(uuid))
@simplecommand("vanishother",
usage = "{player} [on/off]",
description = "Toggles vanish mode for someone, hiding them and their online status from other players.",
amin = 1,
amax = 2,
helpNoargs = True,
helpSubcmd = True)
def vanishother_command(sender, command, label, args):
target = server.getPlayer(args[0])
Validate.notNone(target, "&cThe specified player is not online")
current_state = is_vanished(target)
new_state = not current_state
if len(args) == 2:
arg = args[1].lower()
if arg == "on":
new_state = True
elif arg == "off":
new_state = False
if current_state == new_state:
return "&cThat player was already vanished!" if current_state else "&cThat player was not yet vanished!"
set_state(target, new_state)
enabled_str = "enabled" if new_state else "disabled"
if target != sender:
msg(target, "&aVanish mode %s by %s" % (enabled_str, sender.getDisplayName() if is_player(sender) else "&9CONSOLE"))
return "&aVanish mode %s%s" % (enabled_str, " for " + target.getDisplayName() if target != sender else "")
-14
View File
@@ -1,14 +0,0 @@
from helpers import *
from java.lang import Runnable
class run(Runnable):
def run(self):
players = server.getOnlinePlayers()
for player in players:
if player.hasPermission("essentials.vanish"):
player.performCommand("vanish")
player.performCommand("vanish")
def enabled():
server.getScheduler().runTaskTimer(server.getPluginManager().getPlugin("RedstonerUtils"), run(), 20, 1200)
+69 -69
View File
@@ -18,96 +18,96 @@ from random import randrange
def mysql_query(query, args, fetch = True): def mysql_query(query, args, fetch = True):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor() curs = conn.cursor()
curs.execute(query, args) curs.execute(query, args)
if fetch: if fetch:
results = curs.fetchall() results = curs.fetchall()
else: else:
results = conn.commit() results = conn.commit()
curs.close() curs.close()
conn.close() conn.close()
return results return results
def generate_token(length): def generate_token(length):
cons = 'bcdfghjklmnpqrstvwxyz' cons = 'bcdfghjklmnpqrstvwxyz'
vows = 'aeiou' vows = 'aeiou'
token = '' token = ''
start = randrange(2) start = randrange(2)
for i in range(0, length): for i in range(0, length):
if i % 2 == start: if i % 2 == start:
token += cons[randrange(21)] token += cons[randrange(21)]
else: else:
token += vows[randrange(5)] token += vows[randrange(5)]
return token return token
def get_token(uuid): def get_token(uuid):
results = mysql_query("SELECT DISTINCT `token`, `email` FROM register_tokens WHERE `uuid` = ? LIMIT 1", (uuid,)) results = mysql_query("SELECT DISTINCT `token`, `email` FROM register_tokens WHERE `uuid` = ? LIMIT 1", (uuid,))
return results[0] if len(results) == 1 else None return results[0] if len(results) == 1 else None
def token_command(sender): def token_command(sender):
plugin_header(sender, "Website Token") plugin_header(sender, "Website Token")
if is_player(sender): if is_player(sender):
try: try:
token = get_token(sender.getUniqueId().toString().replace("-", "")) token = get_token(sender.getUniqueId().toString().replace("-", ""))
if token: if token:
msg(sender, "&aEmail: &e%s" % token[1]) msg(sender, "&aEmail: &e%s" % token[1])
msg(sender, "&aToken: &e%s" % token[0]) msg(sender, "&aToken: &e%s" % token[0])
msg(sender, "&cIMPORTANT: never share the token with anyone!") msg(sender, "&cIMPORTANT: never share the token with anyone!")
msg(sender, "&cIt could be used to claim your website account!") msg(sender, "&cIt could be used to claim your website account!")
else: else:
msg(sender, "&cYou don't have a token yet! Use &e/gettoken <email>&c.") msg(sender, "&cYou don't have a token yet! Use &e/gettoken <email>&c.")
except Exception, e: except Exception, e:
error(e) error(e)
msg(sender, "&cError getting your token, please contact an admin!") msg(sender, "&cError getting your token, please contact an admin!")
else: else:
msg(sender, "&cThis is only for players..") msg(sender, "&cThis is only for players..")
def tokengen_command(sender, args): def tokengen_command(sender, args):
plugin_header(sender, "Website Token") plugin_header(sender, "Website Token")
if is_player(sender): if is_player(sender):
if len(args) < 1: if len(args) < 1:
msg(sender, "&cPlease use &e/gettoken <email adress>") msg(sender, "&cPlease use &e/gettoken <email adress>")
else:
# email may contain spaces
mail = " ".join(args)
# email regex, needs something followed by an @ followed by domain or IP
if match("^.+@(.+\\..{2,}|\\[[0-9a-fA-F:.]+\\])$", mail) != None:
token = generate_token(6)
uuid = sender.getUniqueId().toString().replace("-", "")
try:
mysql_query("DELETE FROM register_tokens WHERE `uuid` = ?", (uuid,), False)
mysql_query("INSERT INTO register_tokens (`uuid`, `token`, `email`) VALUES (?, ?, ?)", (uuid, token, mail), False)
msg(sender, "&aToken generated!")
msg(sender, "&aEmail: &e%s" % mail)
msg(sender, "&aToken: &e%s" % token)
msg(sender, "&cIMPORTANT: never share the token with anyone!")
msg(sender, "&cIt could be used to claim your website account!")
except Exception, e:
error(e)
msg(sender, "&cError getting your token, please contact an admin!")
else:
msg(sender, "&c'&6%s&c' doesn't look like a valid email adress!" % mail)
else: else:
msg(sender, "&cThis is only for players..") # email may contain spaces
mail = " ".join(args)
# email regex, needs something followed by an @ followed by domain or IP
if match("^.+@(.+\\..{2,}|\\[[0-9a-fA-F:.]+\\])$", mail) != None:
token = generate_token(6)
uuid = sender.getUniqueId().toString().replace("-", "")
try:
mysql_query("DELETE FROM register_tokens WHERE `uuid` = ?", (uuid,), False)
mysql_query("INSERT INTO register_tokens (`uuid`, `token`, `email`) VALUES (?, ?, ?)", (uuid, token, mail), False)
msg(sender, "&aToken generated!")
msg(sender, "&aEmail: &e%s" % mail)
msg(sender, "&aToken: &e%s" % token)
msg(sender, "&cIMPORTANT: never share the token with anyone!")
msg(sender, "&cIt could be used to claim your website account!")
except Exception, e:
error(e)
msg(sender, "&cError getting your token, please contact an admin!")
else:
msg(sender, "&c'&6%s&c' doesn't look like a valid email adress!" % mail)
else:
msg(sender, "&cThis is only for players..")
@hook.command("token") @hook.command("token")
def on_token_command(sender, command, label, args): def on_token_command(sender, args):
thread.start_new_thread(token_command, (sender,)) thread.start_new_thread(token_command, (sender,))
return True return True
@hook.command("gettoken") @hook.command("gettoken")
def on_gettoken_command(sender, command, label, args): def on_gettoken_command(sender, args):
thread.start_new_thread(tokengen_command, (sender, args)) thread.start_new_thread(tokengen_command, (sender, args))
return True return True