617 Commits
Author SHA1 Message Date
jomo b5fbab06b4 /plotter must be run by player 2015-08-13 00:03:05 +02:00
jomo f09a0ae083 restructure plotter, use Plot class 2015-08-12 23:48:16 +02:00
jomo 50e4e947c8 detect if standing on pathway 2015-08-12 23:05:02 +02:00
jomo 5a80c74b9a turn plotter.py into actual plugin, not cli tool 2015-08-12 22:00:03 +02:00
NEMESIS13cz c521b8fa86 Removed plotgen.py, added plotter.py to module list 2015-08-11 21:18:03 +02:00
NEMESIS13cz d3d6257496 Removed 2015-08-11 21:17:44 +02:00
NEMESIS13cz c6ffa5de64 Added getDefaultGenerator 2015-08-11 21:05:58 +02:00
NEMESIS13cz e45e3e3e44 Created the plot-generator 2015-08-11 21:05:38 +02:00
NEMESIS13cz f865c02bf5 Added support for hex strings 2015-08-11 03:35:23 +02:00
NEMESIS13cz 6e5829f9d2 Fixed loading issues 2015-08-11 03:15:17 +02:00
NEMESIS13cz d683203aca Rewrote a lot, added a lot 2015-08-11 02:45:03 +02:00
NEMESIS13cz 77f445002c Merge branch 'dev' of https://github.com/RedstonerServer/redstoner-utils into dev 2015-08-10 20:41:35 +02:00
NEMESIS13cz 69fe651dc1 Changed calc to run on a separate thread 2015-08-10 20:40:03 +02:00
PanFritz 2a7b4a05ff custom player class idea 2015-08-10 20:38:42 +02:00
NEMESIS13cz 41d2f31048 Removed hard-coded aliases 2015-08-10 19:53:02 +02:00
NEMESIS13cz 9b3e0d19c4 Fixed error when user logs in multiple times while thread is processing hashes 2015-08-10 19:34:18 +02:00
NEMESIS13cz 09bcc687bc Removed unused stuff 2015-08-10 19:33:04 +02:00
NEMESIS13cz 3500eabde8 Changed kick timeout to 30 seconds 2015-08-10 19:25:37 +02:00
NEMESIS13cz 8edca18bb3 Fixed kick thread 2015-08-10 19:19:26 +02:00
NEMESIS13cz 3b7b61f374 Removed nickname print, dot suffixes cannot be parsed into ASCII 2015-08-10 19:06:01 +02:00
NEMESIS13cz 1faf153d75 Fixed more stuff 2015-08-10 18:57:17 +02:00
NEMESIS13cz 9e796f881e Minor fixes 2015-08-10 18:42:23 +02:00
NEMESIS13cz f45e3fa72b Fixed missing bracket 2015-08-10 18:19:57 +02:00
NEMESIS13cz 63462d6f1d Added player info command 2015-08-10 18:14:18 +02:00
NEMESIS13cz 2a53432c95 Added playermanager to module list 2015-08-10 17:38:59 +02:00
NEMESIS13cz 3f51d2dc25 Finished adding all helper functions 2015-08-10 17:37:24 +02:00
NEMESIS13cz 7e49ca9817 Fixed double message when act is on and ac_key is used 2015-08-10 16:45:18 +02:00
NEMESIS13cz 366d57c47f Created central Player class 2015-08-10 16:44:08 +02:00
NEMESIS13cz 90872da066 Fixed timed-match scheduling 2015-07-23 01:27:38 +02:00
NEMESIS13cz 09e0d761f5 modified: loginsecurity.py
Fixed scheduler and commands
2015-07-23 01:20:07 +02:00
PanFritz f64d3074e1 Merge branch 'master' into dev 2015-07-08 02:34:49 +02:00
PanFritz f661344299 Changed import 2015-07-08 02:20:04 +02:00
PanFritz 62fefcd7f9 Removed player interact entity event from blocked events 2015-07-08 01:57:42 +02:00
PanFritz e0daff2c86 helpNoargs = False 2015-07-08 01:55:45 +02:00
PanFritz 0695040988 set amax = 0 2015-07-08 01:52:05 +02:00
PanFritz 4a18474557 Removed usage from simple command 2015-07-08 01:50:08 +02:00
PanFritz 1689ddaab2 Fixed if statement for password removal 2015-07-08 01:45:23 +02:00
PanFritz 28e9a0dfad Fixed syntax 2015-07-08 01:41:28 +02:00
PanFritz 5f8ba18e53 Threaded password verifying, removed some checks 2015-07-08 01:39:02 +02:00
PanFritz b67d3efbb4 removed commented code, fixed mysql issues. commented out timing thread 2015-07-07 21:56:24 +02:00
PanFritz c8895f9bb4 Fixed mysql command missing '?' 2015-07-07 18:52:43 +02:00
PanFritz b65c2228f7 Fixing syntax errors 2015-07-07 13:07:07 +02:00
PanFritz 93965cef7e Changed import to secret 2015-07-07 13:05:19 +02:00
PanFritz 8971523d6d commented out debug code 2015-07-07 13:04:29 +02:00
PanFritz dac228800c fixed import 2015-07-07 02:09:47 +02:00
PanFritz 6bb52ed255 Finished login security, added mysql support and password hashing. 2015-07-07 01:58:05 +02:00
PanFritz 39b179cf42 Changed snowball damage to floats 2015-07-06 21:46:44 +02:00
PanFritz 839baffb24 Removed debug code, added more comments 2015-07-06 21:04:57 +02:00
PanFritz 9d61d3d61c Fixed async bug on timings thread. Fixed stats sorting 2015-07-06 20:54:09 +02:00
PanFritz 0f47853a41 Changed name to object 2015-07-01 17:17:51 +02:00
PanFritz eec11b857e Changed from sender name to sender object in quit_arena 2015-06-30 19:20:10 +02:00
PanFritz bced8beeda Changed quiting arenas to use player object and not name of player. Timing thread added try except 2015-06-30 19:11:48 +02:00
PanFritz 168d99d9a1 re enabled snowbrawl 2015-06-29 23:59:49 +02:00
PanFritz dd960b909c updated snowbrawl 2015-06-29 23:55:07 +02:00
PanFritz 1c3f2c898c Fixed match start issue 2015-06-29 23:16:39 +02:00
PanFritz 525e4825c6 more indentation fixes 2015-06-29 22:58:47 +02:00
PanFritz fdaa6265c4 Removed old code from main 2015-06-29 22:47:43 +02:00
PanFritz 72723840ed Fixed indentation 2015-06-29 22:47:06 +02:00
PanFritz 474ce0b310 remade snowbrawl 2015-06-29 22:16:18 +02:00
PanFritz 4f30fb1a83 upped explosion damage 2015-06-15 23:10:08 +02:00
PanFritz 98ae25df50 fixed indent issue 2015-06-15 22:40:04 +02:00
PanFritz caec2fd0d5 added snowbrawl to main.py 2015-06-15 22:36:50 +02:00
PanFritz 3a02a4cffc tweaks 2015-06-15 22:27:17 +02:00
Dico200 5f0d845ec0 Nemes's work on Snowbrawl 2015-06-14 17:02:42 +02:00
Dico200 40137cad4c This /up fix SHOULD WORK! 2015-06-06 12:13:18 +02:00
Dico200 35b1fe3a0f Well //up is gone again. Great. Undoing.. 2015-06-06 10:56:31 +02:00
Dico200 778fd0234e Fix /up
Tried a lot of shit but these 3 lines should do it.
2015-06-06 10:29:24 +02:00
Dico200 1b5f07f7aa Fix new attempt... :D 2015-06-03 01:26:27 +02:00
Dico200 dbeb0d53bb Another fix attempt for /up 2015-06-03 01:24:45 +02:00
Dico200 0ea2760bf4 Revert "why did //up disappear? Testing on dev server."
This reverts commit a6f5156ef4.
2015-06-03 01:18:18 +02:00
Dico200 a6f5156ef4 why did //up disappear? Testing on dev server. 2015-06-03 01:16:14 +02:00
Dico200 3cbb8dc9bd Prevent /up griefing, add /ackey, minor tweaks
Dunno why its posting 'changes' in main.py tho
2015-06-03 01:09:07 +02:00
Dico200 794f0470bf blockplacemods fix config types sharing storage obj 2015-05-18 23:34:00 +02:00
Dico200 fb3e4afe3c blockplacemods tweaks/fixes of returned messages 2015-05-18 23:32:57 +02:00
Dico200 5dba052fa9 Forgot to save this last check 2015-05-18 23:06:24 +02:00
Dico200 bd05374db0 blockplacemods update, basecommands fix
Added settings: piston, dropper, hopper
changes to the framework
made it so you can set the default contents for all slots in
furnaces/droppers as well as furnaces.
2015-05-18 23:05:54 +02:00
Dico200 057b404b03 Small change to open_json_file() 2015-05-18 23:00:54 +02:00
Dico200 dd1f0b8356 Steps towards even easier command handling.
See issue #4
2015-05-14 04:10:04 +02:00
Dico200 4599ae89e9 Fix this thing so that only 1 player has to sleep
untested
2015-05-14 03:32:34 +02:00
Dico200 6fc168eb63 Fixes, tweaks, changes 2015-05-14 02:46:54 +02:00
Dico200 83eb3a8885 Merge remote-tracking branch 'origin/dev' 2015-05-14 02:19:16 +02:00
Dico200 59816b58e2 Almost complete redo of blockplacemods, small fixes
I've redone most of blockplacemods its code. It is now MUCH easier to
expand in the future and I think the code is more elegant and stuff. It
all works the same as before, except the command is now /toggle
<setting>
I've merged the setting for /autotakewater and /autofillcauldron into
one setting named cauldron.
2015-05-14 02:16:33 +02:00
Dico200 0ef318d6b9 Removed a lot of shit from basecommands.py 2015-05-13 21:39:25 +02:00
Dico200 9f4d096a57 Cleanup misc.py and small fix, also in damnspam 2015-05-13 21:37:53 +02:00
Dico200 230e427f04 Fix BlockBreakEvent being called on lever switch 2015-05-13 21:37:23 +02:00
Dico200 88e0a298b5 Added a few untested things to misc.py 2015-05-13 21:06:26 +02:00
Dico200 7407ec0513 Merge remote-tracking branch 'origin/dev' 2015-05-08 13:47:23 +02:00
Dico200 6865e2c3b9 Revert "show network AS in /check"
This reverts commit 181c6ccfeb.
2015-05-05 16:50:55 +02:00
Dico200 eaf0f41746 Revert "use https for ipinfo.io"
This reverts commit 62569c7361.
2015-05-05 16:50:48 +02:00
Dico200 37dc80305f More blockplacemods
Trying to make it place an item (in this case 1 piece of redstone dust)
in a furnace. I know that it creates the ItemStack correctly, I know
that in this case .getInventory() returns an instance of
FurnaceInventory and I know that .update() is returning True meaning it
updated the blockstate successfully. However, the item is not appearing
in the furnace. Any idea why?
2015-05-01 21:46:24 +02:00
Dico200 ad9de19d5d right clicking empty cauldron fills it 2015-04-29 17:12:39 +02:00
Dico200 884e0a3491 Added perm check to interactevent im blockplacemods
fixes #19
2015-04-29 14:41:48 +02:00
Dico200 5e8c906bf0 Merge remote-tracking branch 'origin/dev' 2015-04-29 03:31:25 +02:00
Dico200 4e1398e514 Disable loginsecurity module 2015-04-29 03:31:01 +02:00
Dico200 3daa191d8b Remove adminnotes noperm notification 2015-04-29 03:30:00 +02:00
Dico200 9eda3ad0ff Merge remote-tracking branch 'origin/dev' 2015-04-29 03:28:17 +02:00
Dico200 1afaec2a08 Small misc cleanup 2015-04-29 03:27:52 +02:00
Dico200 c451b2247b Added blockplacemods module
Adds a few nifty features with per player customization:
- Placing a slab automatically turns it upside-down
- Placing a cauldron automatically fills it
- Right clicking a cauldron with empty hand or redstone dust lowers
water level
2015-04-29 03:27:37 +02:00
Dico200 1cac4c6ed5 Added /tempadd command: temporary group membership
Just a simpler way of writing /pex user <user> group add <group> *
604800
2015-04-28 00:08:33 +02:00
jomo 62569c7361 use https for ipinfo.io 2015-04-20 21:02:07 +02:00
jomo 181c6ccfeb show network AS in /check 2015-04-20 20:39:00 +02:00
Dico200 487375dd07 Added loginsecurity module
Added to make an easily adjustible version of LoginSecurity.
LoginSecurity does not (seem to) support name changes since it retrieves
the UUID used from a byte[] of "OfflinePlayer:<username>" which means
the UUID changes when a player changes their name. This should fix
/rmpass. It uses BCrypt. I'll test this on the dev server (hoping bcrypt
is installed)
2015-04-17 00:10:21 +02:00
Dico200 5384190741 Adminnotes fix continued message used for next note
Also code cleanup
2015-04-16 18:35:48 +02:00
PanFritzandDico200 7359437524 Fix missing var 2015-04-16 18:35:47 +02:00
Dico200 ab1087f210 Adminnotes fix continued message used for next note
Also code cleanup
2015-04-16 18:33:09 +02:00
PanFritz 7c30af86f2 Fix missing var 2015-04-16 12:40:30 +02:00
PanFritz a37fb90b06 Tab indent fix 2015-04-16 12:36:16 +02:00
PanFritz 62059e613e Added perm check for Admin notes notification 2015-04-16 12:28:58 +02:00
PanFritz 7824fdae54 Added perm check for Admin notes notification 2015-04-16 12:26:03 +02:00
Dico200 2c1292015b Made lava not break redstone components in Creative
I tested thoroughly. I don't see how this will break other parts of the
plugin either.
2015-04-14 21:20:55 +02:00
PanFritz f45da9bf42 Fix missing () 2015-04-13 20:57:25 +02:00
Dico200 055a9073f4 Hotfix in /sudo 2015-04-13 18:38:16 +02:00
Dico200 85df528fc3 Added /rp list as alias for /rp open 2015-04-13 18:38:03 +02:00
Dico200 2c063d638f Tweaks in imout, primarily making player vanish 2015-04-13 18:16:40 +02:00
Dico200 211fb08265 Removed color support for /me for players w/o perms 2015-04-13 18:16:00 +02:00
Dico200 ce3b911b35 /pluginversions is broken, Fixed mail send colours.
I attempted to fix /pluginversions but ended up just commenting it out.
The problem is in retrieving the plugins where instead of object type
Plugin it returns "array.array"? I tried a whole bunch of things but I
didn't succeed to make it work.
2015-04-10 23:55:30 +02:00
Dico200 b232cbf5cf Small fix 2015-04-10 00:39:09 +02:00
Dico200 f3833a6733 Untested change to add pyeval possibility to args
so you do like, for example:
/pex user EVAL:server.getOfflinePlayer("Dico200").getUniqueId()

this could also be used in chat. I know its pretty useless but useful in
some cases.
2015-04-10 00:37:51 +02:00
Dico200 d85b96f875 Clean up misc.py, add space support for cg key 2015-04-10 00:13:06 +02:00
Dico200 9a0767676c Didn't upload this for some reason 2015-04-09 01:39:41 +02:00
Dico200 58eea64148 I love less-than-one line list creators! 2015-04-09 01:38:58 +02:00
Dico200 812e2c3aaf Changed version to 3.1.0 :D no reason 2015-04-09 01:25:52 +02:00
Dico200 9ddd523c58 Added player configurable chatgroup keys
The keys are stored in chatgroup_keys.json
2015-04-09 01:23:00 +02:00
Dico200 34b59e61fe Revert "Revert "Change to /modules... trying to make @command work.""
This reverts commit da756d69cc.
2015-04-08 22:34:44 +02:00
Dico200 da756d69cc Revert "Change to /modules... trying to make @command work."
This reverts commit 201c766119.
2015-04-08 22:32:54 +02:00
Dico200 201c766119 Change to /modules... trying to make @command work.
@command throws an error when it tries to access current_subs, which
supposedly didn't exist. current_subs stores all subcommands found when
defining the method which @command was added to. (These SHOULD be called
first)
2015-04-08 22:32:14 +02:00
Dico200 f7abc20ca1 Don't even bother. 2015-04-03 02:04:25 +02:00
Dico200 de43b0d0db Added (sub/main)command, removed abot error check
@command is untested.
2015-04-03 02:01:57 +02:00
Dico200 661e25dc67 Some tweaks and updates 2015-03-29 12:48:32 +02:00
Dico200 6590a8d30a Added cmd check to ABOT, commented out advancedcmd
advancedcmd doens't work atm, apparently
function.func_code is a thing but adding co_consts isn't an attribute of
that.

Tested abot, seems to work well.
2015-03-28 16:39:09 +01:00
Dico200 4cfa3a598f Tiny tweaks in basecommands.py 2015-03-26 16:48:54 +01:00
Dico200 75823ed042 Added basecommands.py
Contains @simplecommand and @basecommand
Slightly alterred simplecommand, made both display the command's
required permission when displaying help if the sender has the
permission "utils.showpermission".

Also a small tweak in misc.py's join listener.
2015-03-26 16:44:21 +01:00
Dico200 9855f62e7b Replaced /pyeval too, untested atm. 2015-03-25 00:55:13 +01:00
Dico200 75c9a86ba3 Replaced /sudo and /me with @simplecommand hook
Also improved simplecommand a little bit.
Don't ask me why it doesn't work in its own file as I have no clue, it
wasn't tracing the errors.
2015-03-25 00:38:56 +01:00
Dico200 d160bbd91a Revert "Moved simplecommand to its own module"
This reverts commit 669c2d0eb8.
2015-03-24 23:45:23 +01:00
Dico200 669c2d0eb8 Moved simplecommand to its own module
The module is named simplecommand.py (wow, didn't expect that!)

And I also cleaned it up a little bit, and tried to make clear how the
fuck it works. This shit is weird.
2015-03-23 23:24:10 +01:00
Dico200 7b8242697a CommandManager works! (Renamed to simplecommand)
See at the bottom of helpers.py!
I'm quite excited for this addition <3
2015-03-23 23:03:11 +01:00
Dico200 f1b2c61411 Fix reports.py. Oops. 2015-03-23 22:04:53 +01:00
Dico200 5f2ee6add9 Added commandmanager module. ALSO UNTESTED!
Will test now.
2015-03-23 21:30:44 +01:00
Dico200 f6de0a6c78 Added synchronizeranks. Untested! 2015-03-23 20:08:38 +01:00
Dico200 8a95dc65f6 Quick fix 2015-03-20 01:28:02 +01:00
Dico200 98774e8f84 Report code cleanup and /rp reopen
These changes are not yet tested!!!
2015-03-20 01:25:35 +01:00
Dico200 71c0f8782c Removed redundant code check and small tweak 2015-03-20 00:07:47 +01:00
Dico200 3bdb56e8a2 Changed reports module fixes #10
Write /rp ingame for new commands n stuff.
2015-03-20 00:06:47 +01:00
Dico200 1750c82208 Changed all CommandExecutor arguments
Added arguments command and label to all command executor functions,
hopefully for massive performance increase.

This is due to the following mess in PythonLoader:
``` Java
@Override
public boolean onCommand(CommandSender sender, Command command, String
label, String[] args) {
boolean result;
if (argcount == -1) {
try {
result = call(4, sender, command, label, args);
argcount = 4;
} catch (PyException e) {
//this could goof up someone ... they'll probably yell at us and
eventually read this code ... fuck them
if (e.type == Py.TypeError && (e.value.toString().endsWith("takes
exactly 3 arguments (4 given)") || e.value.toString().endsWith("takes
exactly 4 arguments (5 given)"))) {
result = call(3, sender, command, label, args);
argcount = 3;
} else if (e.type == Py.TypeError && (e.value.toString().endsWith("takes
exactly 2 arguments (4 given)") || e.value.toString().endsWith("takes
exactly 3 arguments (5 given)"))) {
result = call(2, sender, command, label, args);
argcount = 2;
} else {
throw e;
}
}
} else {
result = call(argcount, sender, command, label, args);
}
return result;
}
```

Note: Still WIP on reports - I'm working on making it keep solved
reports to fix issue 10
2015-03-19 23:51:33 +01:00
Dico200 d993cc223a Changed AC from toggle or , fixes #16
This solution to log any AC isn't very optimised as it will check for
permission twice. Any fix for this?

Anyways it now runs /ac <msg> from the player every time.
2015-03-19 22:02:07 +01:00
Dico200 40fa9c0692 simplified /me in misc.py
Replaced online user iteration with broadcast method
2015-03-19 21:51:13 +01:00
Dico200 5d23fe490b Remove annoying Damnspam plugin header
I hate plugin_header, can we maybe make it return a string which we
append the message to instead? ._.
or create like plugin_message(String pluginname, Player recipient,
String message)
2015-03-19 20:25:47 +01:00
Dico200 9476a1b0b7 Remove redundant try/catch 2015-03-18 22:26:54 +01:00
Dico200 194958f034 me cmd appearance hotfix (made new cmd) fixes #15 2015-03-18 22:25:58 +01:00
Dico200 55ac6c0977 Change /sudo command fixes #14 2015-03-18 21:09:49 +01:00
Dico200 39654bf4a7 Re-enabled AdminNotes module 2015-03-17 00:56:50 +01:00
jomo 4357c46085 copy dict keys before iterating
python doesn't like changing dicts while iterating over that dict
2015-03-15 05:00:04 +01:00
jomo 1db0ac4cd5 Revert "remove redundant loop"
This reverts commit cc50dc30bc.
2015-03-15 04:40:09 +01:00
jomo 1e7bd51b3b debug pmutils player leave event 2015-03-15 04:36:08 +01:00
jomo cc50dc30bc remove redundant loop 2015-03-15 04:28:56 +01:00
jomo a87ad7b2e9 fix all bukkit/uuid issues in pmtoggle 2015-03-15 04:26:53 +01:00
jomo dbfc1dd2a2 merge 2015-03-15 04:19:02 +01:00
Dico200 f1856d3243 Disable adminnotes, fix stuff 2015-03-15 04:17:12 +01:00
Dico200 5ef17713a4 Change runas() in helpers to use player.chat 2015-03-15 04:03:40 +01:00
Dico200 96b4cb2e3f Disabled snowbrawl 2015-03-15 04:00:51 +01:00
Dico200andjomo 88a935f473 Fixed UUID problem in Pmtoggle
Thanks @jomo  for pointing out
2015-03-15 03:00:55 +01:00
Dico200andjomo ad70989a40 Add colon in pmtoggle 2015-03-15 03:00:55 +01:00
Dico200andjomo a24c7092f7 Add check if chatevent is cancelled in pmtoggle 2015-03-15 03:00:52 +01:00
Dico200andjomo dc307fc5f0 cherry-pick pmtoggle into master 2015-03-15 03:00:18 +01:00
jomo 966943b9a2 Merge branch 'master' into dev 2015-03-15 02:58:03 +01:00
Dico200 1b2b3c2fa9 Fixed UUID problem in Pmtoggle
Thanks @jomo  for pointing out
2015-03-15 02:41:58 +01:00
Dico200 c0c1879fde Add colon in pmtoggle 2015-03-15 02:30:52 +01:00
Dico200 017d53928a Add check if chatevent is cancelled in pmtoggle 2015-03-15 02:30:33 +01:00
Dico200 bab2a6e198 Added pmtoggle to shared["load_modules"] in main 2015-03-15 02:20:41 +01:00
Dico200 5a669893b4 Remove redundant try/except in Pmtoggle module 2015-03-15 02:18:02 +01:00
Dico200 9a3942c034 pmtoggle works now, Fixes comments by Jomo
BTW: I didn't use retrieve_player as it gets an Offline player which
makes it slower and I know the player is online. That's why I used
Bukkit.getPlayer(juuid(uuidstring)). (line 40)
2015-03-15 02:16:30 +01:00
Dico200 43a8ec9481 Added pmtoggle module
pmtoggle adds /tm [player](togglemessage).
When activated, any chat message you send will be sent as:
/msg [player] [msg]
2015-03-15 01:13:36 +01:00
Dico200 1fd3d591f9 Fixed a little code in snowbrawl.py... even if its an outdated version. 2015-02-21 15:55:41 +01:00
jomo 2246b9f5a8 fix mentio color codes 2015-02-09 21:31:31 +01:00
PanFritz 60181bd657 Removed . from operators, remade line 17 2015-01-17 14:33:49 +01:00
PanFritz 9b4d73cfe2 Added check for . 2015-01-17 14:03:20 +01:00
PanFritz c1a69c6a62 Fixed, upping snowball damaga 2015-01-17 05:31:32 +01:00
PanFritz 3bcfe42d65 Fixed, upping snowball damaga 2015-01-17 05:30:15 +01:00
PanFritz ebe7b433ac Fixed, upping snowball damaga 2015-01-17 05:29:08 +01:00
PanFritz 511e4aa543 Fixed, upping snowball damaga 2015-01-17 05:27:52 +01:00
PanFritz 97733e7701 Fixed, upping snowball damaga 2015-01-17 05:17:27 +01:00
PanFritz 194d10b3c2 Fixed, upping snowball damaga 2015-01-17 05:16:28 +01:00
PanFritz b8df8f8a6b Fixed, upping snowball damaga 2015-01-17 05:15:04 +01:00
PanFritz c6ff9ccfa7 Fixed, upping snowball damaga 2015-01-17 05:13:38 +01:00
PanFritz f9a99aaf0b Fixed, upping snowball damaga 2015-01-17 04:51:22 +01:00
PanFritz 955e40dc34 Fixed, upping snowball damaga 2015-01-17 04:49:41 +01:00
PanFritz eba2b6731f Fixed, upping snowball damaga 2015-01-17 04:47:30 +01:00
PanFritz a18cc32c60 Fixed, upping snowball damage 2015-01-17 04:41:45 +01:00
PanFritz 02d073eb2c Changed entity name 2015-01-17 04:40:10 +01:00
PanFritz c062ce6782 changed getType to getTypeId 2015-01-17 04:36:41 +01:00
PanFritz ea3331f540 changed getType to getTypeId 2015-01-17 04:34:21 +01:00
PanFritz 583e2cd4f9 changed getType to getTypeId 2015-01-17 04:31:03 +01:00
PanFritz 041bc029ca More debug code 2015-01-17 04:25:23 +01:00
PanFritz 8efd791e54 debug 2015-01-17 04:24:08 +01:00
PanFritz 59c5c8ed02 import 2015-01-17 04:19:03 +01:00
PanFritz d67b96debe snowbrawl fix. event.getEntity() 2015-01-17 04:13:27 +01:00
PanFritz 8937f634e0 snowbrawl fix. event.getEntity() 2015-01-17 04:08:07 +01:00
PanFritz cdc747b740 added import 2015-01-17 01:18:06 +01:00
PanFritz 973ae69fb4 syntax fix 2015-01-17 01:06:35 +01:00
PanFritz 1c4ec9227e update explosion 2015-01-17 01:04:44 +01:00
PanFritz a86331c33d added import 2015-01-17 00:47:49 +01:00
PanFritz e072580c0d changed event name 2015-01-17 00:44:21 +01:00
PanFritz 759baa869a changed event name 2015-01-17 00:41:17 +01:00
PanFritz 46b3946ee7 commented un needed stuff 2015-01-17 00:38:25 +01:00
PanFritz db4dd3c861 fixed module 2015-01-17 00:35:29 +01:00
PanFritz ce332e7c7c org.bukkit.event.entity.ProjectileHitEvent 2015-01-17 00:34:10 +01:00
PanFritz 5fc18d034f added debug code 2015-01-17 00:21:42 +01:00
PanFritz bc2c5196b2 added snowbrawl to modules 2015-01-17 00:03:49 +01:00
PanFritz 8cc089a11b added snowbrawl.py 2015-01-17 00:01:00 +01:00
PanFritz 496a5d2735 aparently i changed damnspam. Fixed 2015-01-16 23:45:17 +01:00
PanFritz 1515777494 added . to maths operator to support floats 2015-01-16 23:40:14 +01:00
Gap 9a42172c4e A space :3 2015-01-14 18:48:41 +01:00
Gap 1ad6651e52 Adds AdminNotes 2015-01-14 18:36:03 +01:00
Gap 3f9e647e25 Fixed typo + forgot variable 2015-01-14 18:35:47 +01:00
Gap 8b5b90513e Adds note module 2015-01-14 18:31:44 +01:00
Gap 86756713a1 Merge branch 'dev' of https://github.com/RedstonerServer/redstoner-utils into dev 2015-01-14 18:30:31 +01:00
Gap 7c6bfd7f12 Adds note module 2015-01-14 18:29:38 +01:00
PanFritz 197ef515b9 Reverted changes 2015-01-13 13:12:00 +01:00
PanFritz 89c5c3e646 Added should_calc check and done expression var 2015-01-13 13:05:22 +01:00
PanFritz f85a8e1bab removed should_calc condition from line 23, replaced break 2015-01-13 12:51:25 +01:00
PanFritz daf325a6e4 testing 2015-01-13 12:48:12 +01:00
jomo c69e8e80b2 420 = blazeit 2015-01-11 00:56:06 +01:00
jomo 9fa736691c only output numbers
we also support shifting (>>, <<), so the > and < characters are allowed which might lead to a bool type output
we don't want to show bool output
2015-01-11 00:00:39 +01:00
jomo 00fd8e4f1e clean up check.py 2015-01-10 22:44:18 +01:00
jomo f9c6df58c5 remove tab 2015-01-10 22:26:49 +01:00
jomo c6dd5ce4a9 add >, <, ~ and % operators to calc 2015-01-10 00:37:03 +01:00
jomo 611d52ea2b Merge branch 'dev' 2015-01-09 23:06:52 +01:00
PanFritz d4813f7dc5 fixed indentation on damnspam 2015-01-09 22:39:20 +01:00
PanFritz 702c8ec2cf fixed indentation on damnspam 2015-01-09 22:31:28 +01:00
PanFritz 248a848b53 Merge branch 'dev' 2015-01-09 21:38:04 +01:00
PanFritz 4a3fcbd1d5 Changed index of results[] to fit array of tuples 2015-01-09 21:16:04 +01:00
PanFritz 22978a1700 Changed index of results[] to fit array of tuples 2015-01-09 21:11:26 +01:00
PanFritz c205f3457e Debug log results 2015-01-09 21:06:08 +01:00
PanFritz f42b1272b5 Progress 2015-01-09 21:04:02 +01:00
PanFritz 4ad849285c Testing converting results to string 2015-01-09 20:58:27 +01:00
PanFritz 1afd238799 More try/except 2015-01-09 20:51:29 +01:00
PanFritz 02bf56bf4a Added try except to str converion 2015-01-09 20:47:29 +01:00
PanFritz 2295350be6 Added try except 2015-01-09 20:45:40 +01:00
PanFritz db940cdd6e possible fix 2015-01-09 20:40:10 +01:00
jomo 65352519c7 link to info, not /faq command on first join 2015-01-09 01:35:40 +01:00
jomo 8eb0948a61 don't need quotes 2015-01-08 00:44:56 +01:00
jomo f465a4caff nope #8 2015-01-08 00:40:18 +01:00
jomo 4f3cd5ba63 possible fix for #8 2015-01-08 00:38:00 +01:00
jomo ae261d3026 fix error on offline players 2015-01-07 02:05:08 +01:00
jomo 8129bf5fd4 fix offline players 2015-01-07 02:01:00 +01:00
jomo e7c4eba51f oops 2015-01-07 01:39:41 +01:00
jomo ef770dd145 fix typo 2015-01-07 01:36:46 +01:00
jomo 60cc678470 show traceback on error 2015-01-07 01:35:26 +01:00
jomo 9230a048af improve check.py 2015-01-07 01:33:18 +01:00
jomo 7f97087ddb fix /check old usernames 2015-01-07 01:05:49 +01:00
jomo 8b2bf3bf72 delete duplicate chat message 2015-01-07 00:55:08 +01:00
jomo 68430fa175 move module descriptions to main.py or modules themself 2015-01-07 00:17:20 +01:00
jomo f579759e60 better comments in misc.py 2015-01-06 23:59:36 +01:00
jomo 9a916ed2cd change indentation from 2 spaces to 4, fix #5 2015-01-06 23:38:42 +01:00
jomo 3435e99432 Revert "Fixed calc when calling toggle"
This reverts commit 825acf330a.
2015-01-06 23:07:56 +01:00
jomo 4eed09946a Merge branch 'dev' of github.com:RedstonerServer/redstoner-utils into dev 2015-01-06 23:05:43 +01:00
PanFritz 1cb1b96755 Added imout to modules 2015-01-06 22:54:17 +01:00
jomo 91d4a1e186 re-implement toggle()'s add=True|False 2015-01-06 22:36:57 +01:00
jomo 50b09138f8 re-add optional arg to toggle() 2015-01-06 22:30:30 +01:00
PanFritz 825acf330a Fixed calc when calling toggle 2015-01-06 22:23:42 +01:00
jomo 7d7d5e16e1 remove junk in toggle() 2015-01-06 22:19:06 +01:00
PanFritz fb4aff2e04 Removed 'add' condition from helpers.py toggle method 2015-01-06 22:08:36 +01:00
jomo d8bd90544b clean up comments 2015-01-06 21:32:40 +01:00
jomo 6310633ebb disable spectator teleportation 2015-01-06 21:29:00 +01:00
Gap 3e6683725e Removed debugging/enhanced output 2015-01-02 14:12:35 +01:00
jomo 01da1ed812 more docs for helpers, removed unused warp() 2015-01-02 02:26:52 +01:00
jomo 8de52f9ab6 use name parameter for toggle() 2015-01-02 02:21:48 +01:00
jomo 11b08a20a1 /calc can only be used on sender 2015-01-02 02:21:11 +01:00
jomo 00dfc770fe add name parameter to toggle() 2015-01-02 02:20:02 +01:00
jomo d92f98307f improve calc, make users savable 2015-01-02 02:17:17 +01:00
jomo f2a30f3aa2 typo 2015-01-02 01:47:43 +01:00
jomo 226ca3ebf1 welcome to python 2015-01-02 01:47:03 +01:00
jomo 310a347bc8 fix badges style and stuff 2015-01-02 01:43:47 +01:00
jomo 6ec7ad23ed stfu pylint 2015-01-02 01:39:43 +01:00
jomo 9110fc2eda more calc improvements 2015-01-02 01:28:39 +01:00
jomo 0842d92187 docs 2015-01-02 01:23:17 +01:00
jomo a51e715bc7 using checkargs 2015-01-02 01:19:10 +01:00
jomo 24cbcb94ab stone_button = stone button 2015-01-02 01:15:25 +01:00
jomo 3e00e52632 better color 2015-01-02 01:14:35 +01:00
jomo 0dcffd0ff3 improve calc.py 2015-01-02 01:07:10 +01:00
Gap 0448386fa7 Final modification for today 2015-01-01 23:33:54 +01:00
Gap e9c78edb46 Forgot comma... -.- 2015-01-01 22:52:13 +01:00
Gap 461cfca4c6 Added check and badges 2015-01-01 22:49:33 +01:00
Gap df24abbf62 Removed debugging shit 2015-01-01 22:48:25 +01:00
Gap 1fd75516a9 Added player reward module 2015-01-01 22:31:53 +01:00
Gap fef075b7d2 Merge branch 'dev' of https://github.com/RedstonerServer/redstoner-utils into dev 2015-01-01 22:27:55 +01:00
Gap e92ed7e752 (+Pan) Added small chat calculator 2015-01-01 22:24:24 +01:00
jomo 792c8405fb add license, fixes #1 2014-12-26 18:28:59 +01:00
jomo 3b2ad46ab9 fix /check output 2014-12-26 18:28:19 +01:00
Derrick Lim 967bda67da /gm finished for now, will remain commented 2014-12-27 00:42:01 +08:00
Derrick Lim e4ab382d98 Squashed some /gm bugs
Thnx sheep
2014-12-27 00:17:53 +08:00
Derrick Lim 0677f8460d Added /gm - commented for now 2014-12-26 18:48:30 +08:00
Gap 41d9f719f9 Enables ACT for players who are set to offline 2014-12-21 15:25:42 +01:00
jomo af29a62096 load check module on start 2014-12-20 18:56:35 +01:00
jomo 6cc2624621 add secrets.py.example 2014-12-20 18:53:52 +01:00
shillingp 1c7460438f Merge branch 'dev' of github.com:RedstonerServer/redstoner-utils into dev 2014-12-20 17:11:17 +00:00
jomo 6fd1f3610d add secrets.py to gitignore 2014-12-20 17:46:04 +01:00
jomo d8e2fbccf7 add secrets.py to gitignore 2014-12-20 17:45:43 +01:00
shillingp 74dfdb580d Added support for damnspam -1 time arguments 2014-12-19 23:28:33 +00:00
jomo 74121f139c use GitHub's wiki :octocat: 2014-12-18 01:16:25 +01:00
jomo 9606e21770 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-12-17 22:19:04 +01:00
jomo ce8683e85a remove windoge line breaks 2014-12-17 22:13:23 +01:00
jomo 46fad3c2f4 remove install script from readme 2014-12-14 23:35:04 +01:00
Louis Vogt 004140b2df Added fake leave / join module 2014-12-12 20:28:23 +01:00
jomo 6f16ed15ea small cleanup 2014-08-10 05:18:06 +02:00
Louis Vogt ad4fb7a700 New check module (shows some statistics) 2014-08-09 02:15:36 +02:00
Louis Vogt b11ed0f9bf Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-08-08 23:39:28 +02:00
jomo 885589eb7b repalce input with lever/button 2014-08-08 05:47:47 +02:00
jomo 5361e0d8db move line to correct position 2014-08-08 05:42:03 +02:00
jomo d0acf1bd36 fixing endless loop 2014-08-08 05:37:45 +02:00
jomo 10d8498ce4 check if player is allowed to remove input 2014-08-08 05:14:22 +02:00
jomo 8ecae8fe23 reset changing_input 2014-08-08 04:33:27 +02:00
jomo f751207865 allowing to update timeouts | not sure if this works ;_; 2014-08-08 04:26:16 +02:00
Louis Vogt 167bc9dfcf Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-08-07 22:51:01 +02:00
jomo ff7e3e4e67 enable damnspam 2014-08-07 22:46:02 +02:00
jomo f9e09d0f86 small bugfixes 2014-08-07 22:41:02 +02:00
jomo 6c164a054a case insensitive /lol search 2014-08-07 04:21:16 +02:00
jomo 5ecd804d63 remove friends plugin. Too buggy! 2014-08-07 03:32:18 +02:00
jomo 34e703bb3e forgot to import thread 2014-08-07 03:31:47 +02:00
jomo 0b98ba42d3 forgot space 2014-08-07 03:03:27 +02:00
jomo 1238ca66f3 more threading / offlineplayer fixes 2014-08-07 02:53:24 +02:00
jomo adaddd7500 use threading for offline players 2014-08-07 02:49:34 +02:00
Louis Vogt 229ee65e2a Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-08-07 02:36:23 +02:00
jomo 0cf6c53405 use new thread for reports list 2014-08-07 02:30:44 +02:00
jomo bea7d369ac get rid of dico's stupid nonsense :3 2014-08-07 02:27:49 +02:00
jomo 6d04f31a8c get rid of offlineplayer in friends 2014-08-07 02:24:45 +02:00
jomo a48919c94c get rid of OfflinePlayer in forcefield 2014-08-07 02:21:44 +02:00
jomo 363f5cddda remove WTF methods from player welcome 2014-08-07 02:19:53 +02:00
jomo 286ca74f71 fix %s 2014-08-07 02:10:36 +02:00
jomo 733e669e8b clarifiy known_player a bit more 2014-08-07 01:50:26 +02:00
Louis Vogt cb8334b533 Modified known_player method 2014-08-07 01:46:53 +02:00
jomo b31e887aa4 better /lol search 2014-08-07 01:39:12 +02:00
jomo 9aeea06ce9 revert to mob.chicken.plop, lavapop can be overheard easiliy 2014-08-07 01:26:28 +02:00
jomo ba9f59c041 add note if no keywords 2014-08-07 01:25:20 +02:00
jomo 82e912d77e change highlight style. (underline hides parts of the next line) 2014-08-07 01:18:11 +02:00
jomo 9404f91e91 keyword must be IN the word, not exaclty the word 2014-08-07 01:17:26 +02:00
jomo 6e65173c4a don't be racist against players with uppercase characters in their name 2014-08-07 01:11:15 +02:00
jomo 43f8f95961 delete mentions if empty 2014-08-07 01:06:19 +02:00
jomo a73b1da7ca rewrite big parts of mentio 2014-08-07 00:59:13 +02:00
jomo 28d0182496 FIX THIS BEFORE MERGING! 2014-07-31 00:07:15 +02:00
jomo 044134f0c4 nicer string concatenating 2014-07-30 23:51:23 +02:00
jomo dc6d4d5f4b remove try/except. fix code if it doesn't work ;) 2014-07-27 23:55:15 +02:00
jomo b0aa83104c catch all exceptions in pyeval 2014-07-27 23:29:55 +02:00
jomo 63810a0782 better name + docs for played_before (renamed to known_player) 2014-07-27 22:44:12 +02:00
jomo 4707b0fd91 more documentation 2014-07-27 22:39:20 +02:00
jomo 81669c62d7 rename log to info 2014-07-27 22:20:18 +02:00
jomo 1ee5d9b456 add warn() logging 2014-07-27 22:17:24 +02:00
jomo 333437e87a readability 2014-07-27 21:52:55 +02:00
jomo f9d1d8a83c mentio readability, remove <> around mention highlight 2014-07-27 19:49:55 +02:00
jomo 9231d23bcb readability 2014-07-27 19:43:06 +02:00
jomo b1a3a92e49 apply file read/save helpers 2014-07-27 19:42:33 +02:00
jomo e9b0ad656b add path to save/open json file 2014-07-27 06:04:31 +02:00
jomo d58d975910 add default to open_json_file 2014-07-27 06:01:52 +02:00
jomo efc3ee439c better use of plugin_header in saylol 2014-07-27 05:41:25 +02:00
jomo e04053e46f add /lol search <text> 2014-07-27 05:28:31 +02:00
Louis Vogt 2a1c2f3919 Wrong receiver; new plop; no simplejson; still 1 bug 2014-07-26 14:19:31 +02:00
jomo 304da99ca4 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-25 00:05:51 +02:00
jomo d2fe36aee3 link to latest python loader jar, remove jython download 2014-07-25 00:05:42 +02:00
Louis Vogt 047c763a23 Enabled custom mentions (not tested yet) 2014-07-24 15:20:23 +02:00
jomo fb60c0c178 allow to reset motd 2014-07-24 02:31:34 +02:00
jomo bdabfc0054 clean up friends.py 2014-07-24 02:12:54 +02:00
jomo 60b523f0d1 readme stuff
- avoid long methods
- clarify errors
- better traceback example
2014-07-24 01:19:55 +02:00
Dico aafac2fe5a Minor change 2014-07-23 01:04:53 +02:00
Dico 8751123f8c Removed useless lines 2014-07-23 00:56:31 +02:00
Dico 1cba2f9db9 Didn't add module last time...? 2014-07-23 00:55:32 +02:00
Dico 5a47cf3c20 Added friends module. Thanks piggly for testing! :D 2014-07-23 00:53:24 +02:00
jomo 2057c81918 remove test code 2014-07-23 00:00:18 +02:00
jomo 7d356f9eb0 trying stuff 2014-07-22 00:46:00 +02:00
jomo a5eb215b5b use &-colors for motd on first load 2014-07-21 02:35:06 +02:00
jomo a9e0c621ec remove test line 2014-07-21 02:34:36 +02:00
jomo 7f74482fa4 fix plugin_header 2014-07-21 02:31:46 +02:00
jomo b295f12d56 raise test error 2014-07-21 02:28:39 +02:00
jomo 3da64f301d add /modules command
lists all modules.
green if loaded, red otherwise
2014-07-21 02:24:43 +02:00
jomo ce8b20aacd fix problem with 'none' permission 2014-07-21 02:07:45 +02:00
jomo befd5a1721 nicer pyeval output 2014-07-21 02:06:15 +02:00
jomo 70668f0210 fix broken broadcast 2014-07-20 17:53:19 +02:00
jomo 3a62687d6e deploying details added to readme 2014-07-20 17:05:15 +02:00
jomo fbf7722831 renamed fyle to f 2014-07-20 16:46:20 +02:00
jomo 878caad751 fix horidicode 2014-07-20 16:37:41 +02:00
Dico 6d3d2edf51 README.md edited online with Bitbucket 2014-07-19 03:10:02 +00:00
Dico ff7053e1b3 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 6ae2f4971a 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 df91adf7fd fix dicallignment 2014-07-19 02:41:44 +02:00
jomo 243b4fab4f use name for CG logs 2014-07-19 02:37:57 +02:00
jomo 18c0ba0b67 fix re-writing variable 2014-07-19 02:32:35 +02:00
jomo 5b1e1ca383 fix dicode 2014-07-19 02:19:12 +02:00
jomo 6268672ccf fix imports 2014-07-19 02:02:42 +02:00
Dico 4966dac92e Minor tweaks and fixes 2014-07-19 02:00:54 +02:00
Dico 7c2306df9c Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-19 01:52:27 +02:00
Dico 775bdc6205 Small fixes and tweaks 2014-07-19 01:51:29 +02:00
jomo f95cb0269c remove forcefield for merge with master 2014-07-19 01:50:35 +02:00
Dico 231a5b8322 Stuff added to helpers.py, forcefield updated to be a lot more efficient (simple change) 2014-07-19 01:39:08 +02:00
Dico 30d670bade 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 d2270ac263 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 5373a1c4a4 wtf git adding random stuff to my files 2014-07-18 02:36:52 +02:00
Dico 835a7aa9fb Happy with this version/build. @Sheep: Don't fix my 'dicode'! 2014-07-18 02:27:24 +02:00
jomo 8db6085d63 use uid(player) helper method 2014-07-17 22:24:45 +02:00
jomo ebf8a22bae using is_creative helper 2014-07-17 22:13:49 +02:00
jomo a5e9fd348f make dicode DRY and more readable 2014-07-17 21:36:05 +02:00
Dico 8701578875 Rewrote velocity calculation. 2014-07-17 17:47:49 +02:00
Dico 15c06f011b Minor fix 2014-07-17 16:06:11 +02:00
Dico 372a831c82 Converted reports module to UUID and minor changes to forcefield module 2014-07-17 15:26:48 +02:00
Dico 2c1c6928a9 removing feature which doesnt work and is stupid 2014-07-17 05:40:54 +02:00
Dico 760d2a4d16 Cool stuff 2014-07-17 05:29:55 +02:00
Dico f45547f808 Another minor change 2014-07-17 05:10:24 +02:00
Dico 9f6186ad15 Minor change 2014-07-17 04:54:44 +02:00
Dico eab60c5502 No saving to files yet, but it definitely works well now. 2014-07-17 04:49:31 +02:00
Dico f709533ade Updates! YAY! 2014-07-17 03:48:14 +02:00
Dico 23f85b4baa Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-17 01:17:28 +02:00
jomo a5e09e3254 show return type in pyeval 2014-07-17 01:16:37 +02:00
Dico 0b94c02757 Working version 2014-07-17 01:13:22 +02:00
jomo 400e8ec4dd undo dicode 2014-07-17 00:52:22 +02:00
Dico cda6984726 Fixing bugs & Cleaning up code. Seems to work well now! 2014-07-17 00:48:41 +02:00
jomo 6afc92102f debugging 2014-07-16 02:15:23 +02:00
jomo 306b479cad debugging 2014-07-16 02:11:52 +02:00
jomo ad94e31d21 use better names, fix bugs 2014-07-16 02:04:02 +02:00
jomo 60a1210fe1 add readability spacing 2014-07-16 01:08:04 +02:00
jomo 930ca56dfc add readability to coding guidelines 2014-07-16 00:59:02 +02:00
jomo 9a0779d168 more code cleanup 2014-07-16 00:49:55 +02:00
jomo a61691bb1d added Pro Tip (tm) 2014-07-16 00:39:25 +02:00
jomo 53519b0901 clarified camelCase usage 2014-07-16 00:38:15 +02:00
jomo d9b8252ab1 corrected s/idToPlayer/java_uuid/ 2014-07-16 00:34:49 +02:00
jomo 1430a454ed removed camelcase, added more coding style to readme 2014-07-16 00:33:43 +02:00
Dico d2ec8b6d3f Sorry for spam 2014-07-15 19:36:50 +02:00
Dico ad885d8707 Fixing movement bugs 2014-07-15 19:16:30 +02:00
Dico 2acd32f80e Think I finally fixed ALL forcefield bugs, command-side-wise 2014-07-15 18:49:36 +02:00
Dico 4b15a85ac8 Fixing moar bugs! 2014-07-15 14:19:45 +02:00
Dico b84a4d837a Fixing bugs... 2014-07-15 14:07:48 +02:00
Louis Vogt 0f5cfe6f2d Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-14 16:23:33 +02:00
Louis Vogt 9bbd6bba27 Added WIP custom words 2014-07-14 16:22:49 +02:00
Dico c4e206f44e Unfixing fix 2014-07-14 13:38:26 +02:00
Dico cce3c028a4 Fixing bugs 2014-07-14 13:32:37 +02:00
Dico ffae4e7d30 Added forcefield whitelist and hopefully fixed some bugs 2014-07-14 13:08:15 +02:00
jomo cf47df82ff check for cancelled event 2014-07-14 06:04:06 +02:00
jomo 4f13e417e9 check if player can build 2014-07-14 06:01:21 +02:00
jomo 4df5a18831 using floats for timeout 2014-07-14 05:57:27 +02:00
jomo 502aa3acc5 better message formatting 2014-07-14 05:42:44 +02:00
jomo 60c6b957f1 need more caffeine 2014-07-14 05:42:23 +02:00
jomo c51d703d1f fix time check 2014-07-14 05:33:46 +02:00
jomo 13b4c8c115 fix plugHeader, store last time 2014-07-14 05:32:14 +02:00
jomo 7dc4d6a88c I should stop using copy pasta 2014-07-14 05:27:59 +02:00
jomo 2979ecb44e range starts at 0 2014-07-14 05:25:57 +02:00
jomo f0e0045f70 cannot join string with ints 2014-07-14 05:24:08 +02:00
jomo a33e9ef88f don't accept 0 args, remove try 2014-07-14 05:20:30 +02:00
jomo 60c5bb9672 add damnspam to load_modules 2014-07-14 05:17:29 +02:00
jomo a6fecec165 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-14 05:16:59 +02:00
jomo 7024fe4845 damnspam 2014-07-14 05:16:48 +02:00
Dico 63a2e9519e Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-14 02:42:45 +02:00
Dico 89cb6d2d2e added forcefield module, will make whitelist option later 2014-07-14 02:40:00 +02:00
jomo 05a68efc43 clarify how to use CG 2014-07-14 01:26:42 +02:00
jomo 879af23f9a logging groupchat messages 2014-07-14 01:25:12 +02:00
jomo bd5dcf1933 add noperm; return true 2014-07-14 01:20:42 +02:00
jomo 62b3f8a270 fix basecolor in abot 2014-07-14 01:20:11 +02:00
jomo fca2e7e1b2 add mising import 2014-07-14 01:17:51 +02:00
jomo 94932ce0bf creating shared dict 2014-07-14 01:16:40 +02:00
jomo 991030b326 getting the right name in pluginversions 2014-07-14 01:00:30 +02:00
jomo 8ee6d0f40a getting the right name in pluginversions 2014-07-14 01:00:06 +02:00
jomo c9763953d4 can't call function before definition 2014-07-14 00:56:46 +02:00
jomo 2a00635606 use json config for abot 2014-07-14 00:54:25 +02:00
jomo 7981591fb7 using jython 2.7b2 2014-07-13 17:10:14 +02:00
jomo 23973651cc typo fix 2014-07-13 17:03:11 +02:00
jomo d67bf75c24 fix merge conflicts 2014-07-13 16:35:21 +02:00
jomo 568b619122 use uuid in CG 2014-07-13 16:34:31 +02:00
Louis Vogt 41e1d3c65e Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-12 11:06:13 +02:00
Louis Vogt e79172af03 Added DamnSpam to descriptions 2014-07-12 11:05:08 +02:00
jomo 241292acce fix double quites 2014-07-12 03:10:42 +02:00
jomo 4b10679030 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-07-12 03:08:10 +02:00
jomo fafba7f5a6 show online users by UUID; add quotes info to readme 2014-07-12 03:08:01 +02:00
Louis Vogt 3ad9503515 Added WIP DamnSpam module 2014-07-12 01:47:32 +02:00
Louis Vogt 0466cb781b Changed single quotes to double quotes 2014-07-12 01:17:13 +02:00
Louis Vogt b8b86be805 Uses UUID now + cg_key is now : 2014-07-11 23:50:27 +02:00
jomo f3c781ab47 more abot fixes 2014-07-11 00:26:49 +02:00
jomo 7cd3151d8c more abot fixes 2014-07-10 23:45:32 +02:00
jomo e78a147a44 match e.g. who can clear plot 2014-07-10 23:36:36 +02:00
jomo 9af08cfe4f remove empty matchgroup; first match has to be a word 2014-07-10 23:35:03 +02:00
jomo 55e3cbc137 fix false positive for e.g. MODel, MODern 2014-07-10 23:32:23 +02:00
jomo 8efb6bcc20 fix false positive for e.g. MODel, MODern 2014-07-10 23:30:35 +02:00
jomo bde3848ee6 skip abot for players with 'utils.ignore_abot' permission 2014-07-10 23:08:23 +02:00
jomo bf0507ee23 fix literal '.' in regex, fixes 2014-07-10 23:06:45 +02:00
jomo 7b742a3152 more noob matching 2014-07-10 22:58:47 +02:00
jomo 07f1a169c3 needs trailing space 2014-07-10 01:22:53 +02:00
jomo 755bd35abb fix typo, nicer output 2014-07-10 01:21:14 +02:00
jomo ec9063b6e7 do not require extra words 2014-07-10 01:11:25 +02:00
jomo 44af737e9e fucking comma 2014-07-10 01:03:39 +02:00
jomo c2814fac4a fix braces 2014-07-10 00:55:04 +02:00
jomo 2248007358 more questions 2014-07-10 00:52:32 +02:00
jomo 43e4015311 add abot (AnswerBot) to get rid of stupid FAQ asking 2014-07-10 00:37:42 +02:00
jomo 16217e1251 fix double plugin header 2014-07-09 00:24:55 +02:00
jomo c34c533dca add /echo 2014-07-09 00:18:26 +02:00
jomo 31112f95a9 make AC prefix red 2014-07-08 20:30:11 +02:00
jomo 4c893342f9 removed unused commands from welcome message 2014-07-08 19:55:54 +02:00
jomo 5ceb3f096c fix out of range /lol id 2014-07-08 02:17:37 +02:00
jomo 1017e64095 use cycle plugin in creative mode only 2014-07-06 20:49:11 +02:00
jomo 4ef56eab97 remove text-only commands, use commands.yml aliases 2014-07-05 21:28:26 +02:00
jomo 52f5f92e73 add 0.4s delay to shearing 2014-07-05 21:12:27 +02:00
jomo ab6e2a0c27 175:6 is no longer breaking clients 2014-07-05 21:05:47 +02:00
jomo da51c6f5fc tell people to use website 2014-07-05 21:05:18 +02:00
jomo c2031cbeed avoid using deleting e.g. reports[-1] 2014-07-05 18:58:22 +02:00
jomo d5e2cf282f fix broken report deletion 2014-07-05 18:54:52 +02:00
jomo 6534922886 allow newlines 2014-07-04 02:04:59 +02:00
jomo 991673779b fix broadcast 2014-07-04 02:00:04 +02:00
jomo d07883d0c4 fix plugin title 2014-07-04 01:54:23 +02:00
jomo 0a309f0f60 fix plugin title 2014-07-04 01:53:33 +02:00
jomo 4791f84356 add motd.py 2014-07-04 01:50:36 +02:00
jomo 8ffa50c436 fix deleteing non-existing report 2014-07-02 01:13:12 +02:00
jomo afdda4e564 fix shearsheep 2014-07-02 00:27:50 +02:00
jomo 15ed89098d fix typi 2014-06-29 18:28:13 +02:00
jomo 327772b03b don't cycle when sneaking 2014-06-29 18:26:02 +02:00
jomo f141f392f8 use strings for UUID 2014-06-29 16:25:17 +02:00
jomo e0e90c796f add newline to plugin headers 2014-06-29 16:22:28 +02:00
jomo 25dce528c4 save file on list change, fix up/down naming, remove logging 2014-06-29 16:21:59 +02:00
jomo f45c1c10dc save file 2014-06-29 16:15:42 +02:00
jomo 24bd4d58c2 fix indentation 2014-06-29 15:38:51 +02:00
jomo 5ed5753b38 better loggin 2014-06-29 15:37:45 +02:00
jomo 4a2cbf7f1f shift items, then check for empty line 2014-06-29 15:33:27 +02:00
jomo 04ab9e93cb shift items, then check for empty line 2014-06-29 15:21:16 +02:00
jomo dd8fe14858 move cycle plugin to new module; add features 2014-06-29 15:18:25 +02:00
jomo 91e826aec0 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-06-29 09:19:43 +02:00
jomo 3697e19d79 use list(x) instead of x.tolist() 2014-06-29 09:19:33 +02:00
shillingp c1cf6b5b06 Complete inventory cycle 2014-06-27 15:16:03 +00:00
jomo f00215c5f5 make gettoken more user-friendly 2014-06-25 02:40:49 +02:00
jomo 98a6659ec4 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-06-25 02:36:07 +02:00
jomo 549b64994d rename tokengen/gettoken 2014-06-25 02:35:47 +02:00
shillingp 23fb4d6644 misc.py edited online with Bitbucket 2014-06-23 23:09:55 +00:00
shillingp 53c9118755 getInventory not getContents 2014-06-23 23:07:25 +00:00
shillingp 794ff39b50 changed inventory event to player event 2014-06-23 22:59:59 +00:00
shillingp 09f2bc6e5e Added inventory cycle function 2014-06-23 22:52:04 +00:00
jomo fa944b4e37 fix comments 2014-06-23 03:16:09 +02:00
jomo 06a0bf8428 Merge branch 'dev' 2014-06-23 01:18:28 +02:00
jomo cf36f6b525 adjust rules 2014-06-23 01:18:15 +02:00
jomo 5a5092ed32 fix rule alignment; change color 2014-06-23 01:02:09 +02:00
jomo ddc700d1a4 fixed wrong prefix in /cgt 2014-06-23 00:34:00 +02:00
jomo 03d0ca1924 add mentio.py again, now working 2014-06-22 02:15:01 +02:00
jomo cd35888164 Merge branch 'dev' 2014-06-22 02:12:05 +02:00
jomo a391165995 awesome new feature 2014-06-22 02:11:43 +02:00
jomo 871f3385f3 fix deprecated event 2014-06-21 14:39:43 +02:00
jomo 7560bf1de3 fixed wrong event priority names 2014-06-21 14:34:00 +02:00
jomo 9a10123179 y u no work 2014-06-21 14:32:07 +02:00
jomo 80018d5deb derp, need to use lower event so ac cancels before mentio 2014-06-21 14:26:24 +02:00
jomo cbf0fa2cf0 Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev 2014-06-21 14:07:15 +02:00
jomo e6b05127c0 use asyncplayerchatevent for adminchat, listen after mentio 2014-06-21 14:07:05 +02:00
jomo c02f93d466 fixed spigot link 2014-06-21 11:06:27 +00:00
jomo 9d4fc9f87b using list(x) instead of x.tolist() 2014-06-21 12:50:03 +02:00
jomo 7dcda40b1a only using recipient list when iterating 2014-06-21 12:47:25 +02:00
jomo eb06427ecf rename tokengen to gettoken, add warning 2014-06-21 12:43:16 +02:00
jomo 63c1f07a72 lots of stuff for readme 2014-06-21 12:38:44 +02:00
jomo c99e283651 catch java exceptions, too 2014-06-21 11:09:10 +02:00
jomo 4e3cecc38d ignore everything in files/ 2014-06-21 11:08:18 +02:00
jomo ade4694999 catch java exceptions, too 2014-06-21 11:05:59 +02:00
Louis Vogt a6b22945d8 Converted set into list 2014-06-21 10:01:35 +02:00
jomo a20f942a0f remove mention due to error spam 2014-06-21 02:29:04 +02:00
jomo 68018d9c2a copying recipients before iterating 2014-06-21 01:18:00 +02:00
jomo a63a28a2c4 catch everything 2014-06-21 01:12:27 +02:00
jomo 610e926a54 quick fix 2014-06-21 01:00:21 +02:00
jomo 151a8525d7 fix colors, highlight word, create sound 2014-06-21 00:52:16 +02:00
jomo 379751e1fb better way to debug plugins 2014-06-20 22:24:20 +02:00
jomo 031dea64e2 add (unused) code to create awesome screenshots :D 2014-06-20 22:23:09 +02:00
Louis Vogt d4a14b4601 Fixed indention. Finally. 2014-06-20 22:16:17 +02:00
Louis Vogt 403348daa3 Fixed intentation+spelling mistake 2014-06-20 22:13:09 +02:00
Louis Vogt 6df5cab599 Added mention module 2014-06-20 22:04:39 +02:00
Louis Vogt f23a6ee05a Added mention module 2014-06-20 21:56:30 +02:00
jomo 43b129770d delete files/ 2014-06-17 00:20:10 +02:00
jomo b36f09aca7 remove tilehelper for master 2014-06-17 00:11:49 +02:00
shillingp 6d63b37d68 spelling mistakes 2014-06-16 22:09:20 +00:00
shillingp 26c5f4d1de Messages altered and colored 2014-06-16 22:03:44 +00:00
shillingp 9752caece4 Fixed fail if statement 2014-06-16 21:53:12 +00:00
shillingp 2604ed499c spawn to teleport command, implemented head position 2014-06-16 21:41:06 +00:00
shillingp 93a2db5532 Import material removed, material as string 2014-06-16 21:24:06 +00:00
shillingp 0db2d58e89 Import materials for Material.PORTAL 2014-06-16 21:21:22 +00:00
jomo 03159d549c Merged in shillingp/portal-safety-1402935495123 (pull request #1)
misc.py added login portal safety
2014-06-16 23:11:58 +02:00
shillingp f22212a093 misc.py added login portal safety 2014-06-16 16:19:32 +00:00
jomo 75cce75aa2 log errors 2014-06-11 23:10:39 +02:00
jomo 12e1191653 use simplejson 2014-06-10 06:32:28 +02:00
jomo 012a98d0e5 load tilehelpers from file 2014-06-10 06:25:25 +02:00
jomo 5e75884482 sleep 2 ticks so changes can be applied 2014-06-10 06:06:40 +02:00
jomo 0f44ad5c53 handle right click 2014-06-10 06:01:59 +02:00
jomo 89d106967a bugfix 2014-06-10 05:43:36 +02:00
jomo 5390a6578d fix block data; use Interact instead of DamageEvent 2014-06-10 05:31:39 +02:00
jomo 34de631403 add BlockDamageEvent 2014-06-10 05:17:44 +02:00
jomo 7eeb34f65c use data from blockstate 2014-06-10 05:15:10 +02:00
jomo cddd3a1dcc add data to blockPlaceEvent 2014-06-10 05:12:18 +02:00
jomo 54e3fd052f remove debug output 2014-06-10 04:57:11 +02:00
jomo 682f22b99d bugfixes 2014-06-10 04:53:36 +02:00
jomo 5175ce5b81 AAAARGH 2014-06-10 04:50:55 +02:00
jomo c95760fe92 cannot believe this... BrakeEvent >_< 2014-06-10 04:47:59 +02:00
jomo d205c096da added BlockBrakeEvent 2014-06-10 04:45:01 +02:00
jomo cd346f9e60 oops 2014-06-10 04:23:13 +02:00
jomo 13a828ad29 trying to use new block AND new block's state 2014-06-10 04:19:41 +02:00
jomo d2d4eff3a7 debugging 2014-06-10 04:17:37 +02:00
jomo 8508b0f2b4 debugging 2014-06-10 04:13:04 +02:00
jomo 0b52b8d79f debugging 2014-06-10 04:01:46 +02:00
jomo cdf17c7f7f debugging 2014-06-10 03:58:40 +02:00
jomo 6218891146 oops, need to use newblock, not newagainst 2014-06-10 03:46:59 +02:00
jomo 1fc6489892 debug 2014-06-10 03:44:02 +02:00
jomo 20d8e506cc using block from blockstate 2014-06-10 03:15:23 +02:00
jomo 36e8b49090 changing blockstate 2014-06-10 03:10:10 +02:00
jomo a32ced6fd5 set block if event was not cancelled 2014-06-10 02:39:50 +02:00
jomo 8b6d163df1 move /pyeval back to main.py, so modules can be accessed 2014-06-10 01:36:18 +02:00
jomo 98620428ec HUGE code cleanup 2014-06-10 01:31:03 +02:00
jomo e466d5426c fix endless loop? 2014-06-10 00:32:48 +02:00
jomo aad5cbe07d fix endless loop 2014-06-10 00:30:54 +02:00
jomo 0f07ad4b27 test 2014-06-10 00:22:54 +02:00
jomo e639f302f0 firing event in defined directions 2014-06-10 00:20:02 +02:00
jomo b55c485c7d add missing import option 2014-06-09 23:54:48 +02:00
jomo 9927935074 better loading / importing of modules 2014-06-09 23:52:11 +02:00
jomo dddbcd7684 remove executable bit 2014-06-07 20:15:46 +02:00
jomo 099de5abe1 remove executable bit 2014-06-07 20:13:10 +02:00
jomo 4381db73fb started tilehelper plugin 2014-06-07 01:27:06 +02:00
jomo a9a540a73e fix path 2014-05-17 01:17:05 +02:00
jomo 97e5e2641c change mode 775 2014-05-17 01:09:35 +02:00
jomo 26d5c584eb add default files to prevent errors on first start 2014-05-17 00:46:22 +02:00
jomo ecedd98ccc remove ingame dependent files 2014-05-17 00:45:00 +02:00
jomo 53c1f8e2cb yea, i actually forgot this plugin itself... >_< 2014-05-17 00:35:32 +02:00
jomo d636f4e974 add README 2014-05-17 00:22:35 +02:00
jomo 57882c8dec rename mysql-connector 2014-05-17 00:14:40 +02:00
jomo 9f1ed1fb66 first commit via git 2014-05-16 23:04:40 +02:00
42 changed files with 4157 additions and 1649 deletions
+4
View File
@@ -1,6 +1,10 @@
*.pyc
*.class
*sublime*
*.bat*
secrets.py
excluded.txt
.idea
# these are player/ingame specific
files/
+1
View File
@@ -0,0 +1 @@
If you want to contribute, please [read through the pages on the wiki](https://github.com/RedstonerServer/redstoner-utils/wiki).
+21
View File
@@ -0,0 +1,21 @@
# 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
+3 -240
View File
@@ -2,245 +2,8 @@
Redstoner's custom plugins, written in python.
------
# Installation / Set-up
## Contributing
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())
```
If you want to contribute, please [read through the pages on the wiki](https://github.com/RedstonerServer/redstoner-utils/wiki).
+13 -4
View File
@@ -27,7 +27,7 @@ def list_answers(sender):
@hook.command("abot")
def on_abot_command(sender, args):
def on_abot_command(sender, command, label, args):
plugin_header(sender, "AnswerBot")
if sender.hasPermission("utils.abot.admin"):
if not args:
@@ -45,10 +45,8 @@ def on_abot_command(sender, args):
return True
@hook.event("player.AsyncPlayerChatEvent", "low")
def on_chat(event):
def check_msg(event, message):
sender = event.getPlayer()
message = event.getMessage().lower()
for answer in answers:
for regex in answer["regex"]:
if regex.search(message):
@@ -60,4 +58,15 @@ def on_chat(event):
break
@hook.event("player.AsyncPlayerChatEvent", "low")
def on_chat(event):
check_msg(event, event.getMessage().lower())
@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()
+36 -5
View File
@@ -1,8 +1,12 @@
#pylint: disable = F0401
from helpers import *
from basecommands import simplecommand
ac_permission = "utils.ac"
ac_key = ","
ac_defaultkey = ","
ac_keys = open_json_file("adminchat_keys", {})
ac_toggle_list = []
ac_prefix = "&8[&cAC&8]"
@@ -13,6 +17,7 @@ def adminchat(sender, msg):
except AttributeError:
name = sender.getName()
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
@@ -41,15 +46,41 @@ def on_ac_command(sender, args):
noperm(sender)
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")
def on_chat(event):
sender = event.getPlayer()
msg = event.getMessage()
if sender.hasPermission(ac_permission) and not event.isCancelled():
if msg[:len(ac_key)] == ac_key:
adminchat(sender, msg[1:])
event.setCancelled(True)
elif sender.getName() in ac_toggle_list:
key = get_key(uid(sender))
if sender.getName() in ac_toggle_list:
adminchat(sender, msg)
event.setCancelled(True)
elif msg[:len(key)] == key:
adminchat(sender, msg[len(key):])
event.setCancelled(True)
+134
View File
@@ -0,0 +1,134 @@
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
@@ -0,0 +1,137 @@
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
+110
View File
@@ -0,0 +1,110 @@
from helpers import *
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 run from the console" if isPlayer else "&cThat command can only be run by 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(e.message, 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("")
+285
View File
@@ -0,0 +1,285 @@
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
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 dropper 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 dropper 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())
"""
+104
View File
@@ -0,0 +1,104 @@
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):
"""
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
+39 -12
View File
@@ -1,15 +1,21 @@
#pylint: disable = F0401
from helpers import *
from basecommands import simplecommand
from java.util.UUID import fromString as juuid
from traceback import format_exc as trace
groups = open_json_file("chatgroups", {})
cg_key = ":"
cg_defaultkey = ":"
cg_keys = open_json_file("chatgroup_keys", {})
cg_toggle_list = []
def get_key(uuid):
key = cg_keys.get(uuid)
return key if key != None else cg_defaultkey
@hook.command("chatgroup")
def on_chatgroup_command(sender, args):
def on_chatgroup_command(sender, command, label, args):
plugin_header(sender, "ChatGroups")
sender_id = uid(sender)
if len(args) == 1 and args[0] == "leave":
@@ -24,12 +30,7 @@ def on_chatgroup_command(sender, args):
if sender_id in groups.keys():
group = groups[sender_id]
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())
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:
@@ -39,15 +40,18 @@ def on_chatgroup_command(sender, args):
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)
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))
else:
msg(sender, "&e/chatgroup join <name>")
msg(sender, "&e/chatgroup leave")
msg(sender, "&e/chatgroup info")
msg(sender, "&e/chatgroup key")
@hook.command("cgt")
def on_cgt_command(sender, args):
def on_cgt_command(sender, command, label, args):
p = uid(sender)
if p in cg_toggle_list:
cg_toggle_list.remove(p)
@@ -84,9 +88,32 @@ def on_chat(event):
msge = event.getMessage()
if not event.isCancelled():
sender_id = uid(sender)
if msge[:len(cg_key)] == cg_key and sender_id in groups.keys():
groupchat(sender, msge[1:])
key = get_key(sender_id)
keylen = len(key)
if msge[:keylen] == key and sender_id in groups.keys():
groupchat(sender, msge[keylen:])
event.setCancelled(True)
elif sender_id in cg_toggle_list:
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)
+92
View File
@@ -0,0 +1,92 @@
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
get_all_data(sender, player)
else:
msg(sender, "&4You don't have the required permissions to execute this command!")
return True
+1 -1
View File
@@ -4,7 +4,7 @@ no_cyclers = open_json_file("cycle", [])
@hook.command("cycle")
def on_cycler_command(sender, args):
def on_cycler_command(sender, command, label, args):
plugin_header(sender, "Cycle")
if not is_player(sender):
msg(sender, "&conly players can do this")
+48 -20
View File
@@ -5,6 +5,8 @@ import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
inputs = open_json_file("damnspam", {}) # format "x;y;z;World"
accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON", "LEVER"]
changing_input = False
removing_input = False
def save_inputs():
@@ -25,10 +27,15 @@ def add_input(creator, block, timeout_off, timeout_on):
@hook.command("damnspam")
def on_dammnspam_command(sender, args):
plugin_header(sender, "DamnSpam")
if len(args) in [1,2]:
def on_dammnspam_command(sender, command, label, args):
global changing_input
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):
msg(sender, "&cYou can only do this in Creative mode.")
return True
@@ -39,8 +46,10 @@ def on_dammnspam_command(sender, args):
try:
timeout_on = round(float(timeout_on), 2)
timeout_off = timeout_on
if not 0 <= timeout_on <= 60:
msg(sender, "&cThe timeout must be within 0-60.")
if 60 >= timeout_on <= -2 or timeout_on == 0:
timeout_on = False
if timeout_on == False:
msg(sender, "&cThe timeout must be within 0-60 or -1.")
return True
except ValueError:
msg(sender, "&cThe timeout must be a number")
@@ -53,8 +62,12 @@ def on_dammnspam_command(sender, args):
try:
timeout_on = round(float(timeout_on), 2)
timeout_off = round(float(timeout_off), 2)
if not 0 <= timeout_on <= 60 or not 0 <= timeout_off <= 60:
msg(sender, "&cThe timeout must be within 0-60.")
if 60 >= timeout_on <= -2 or timeout_on == 0:
timeout_on = False
if 60 >= timeout_off <= -2 or timeout_off == 0:
timeout_off = False
if timeout_on == False or timeout_off == False:
msg(sender, "&cThe timeout must be within 0-60 or -1.")
return True
except ValueError:
msg(sender, "&cThe timeout must be a number")
@@ -67,39 +80,52 @@ def on_dammnspam_command(sender, args):
msg(sender, "&cPlease look at a button or lever while executing this command!")
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)
server.getPluginManager().callEvent(test_event)
changing_input = False
if test_event.isCancelled():
msg(sender, "&cYou are not allowed to modify this button")
msg(sender, "&cYou are not allowed to modify this %s" % str(target.getType()).lower())
return True
# add block to inputs
add_input(sender, target, timeout_off, timeout_on)
save_inputs()
msg(sender, "&aSuccessfully set a timeout for this %s." % ttype.lower())
msg(sender, "&aSuccessfully set a timeout for this %s." % ttype.lower().replace("_", " "))
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")
def on_block_break(event):
global removing_input
if removing_input:
return
sender = event.getPlayer()
block = event.getBlock()
btype = str(block.getType()).lower()
if str(block.getType()) in accepted_inputs and not event.isCancelled():
pos_str = location_str(block)
if inputs.get(pos_str):
plugin_header(sender, "DamnSpam")
if sender.isSneaking():
# test if player is allowed to build here
removing_input = True
test_event = BlockBreakEvent(block, sender)
server.getPluginManager().callEvent(test_event)
removing_input = False
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 the input!")
msg(sender, "&eSuccessfully removed this %s!" % btype)
return True
else:
elif not changing_input:
event.setCancelled(True)
msg(sender, "&cYou cannot destroy this input!")
msg(sender, "&cYou cannot destroy this %s!" % btype)
msg(sender, "&c&nSneak&c and break if you want to remove it.")
return True
@@ -115,9 +141,11 @@ def on_interact(event):
data = inputs.get(pos_str)
if data:
checktime = data["timeout_on"] if powered else data["timeout_off"]
if data["last_time"] + checktime > now():
if checktime == -1:
event.setCancelled(True)
plugin_header(sender, "DamnSpam")
msg(sender, "&cThis %s has a timeout of %ss." % (btype, checktime))
msg(sender, "&cThis %s is locked permanently by /damnspam." % (btype))
elif data["last_time"] + checktime > now():
event.setCancelled(True)
msg(sender, "&cThis %s has a damnspam timeout of %ss." % (btype, checktime))
else:
inputs[pos_str]["last_time"] = round(now(), 2)
+6 -2
View File
@@ -1,4 +1,5 @@
#pylint: disable = F0401
import thread
from helpers import *
from org.bukkit.util import Vector
from math import sin
@@ -16,7 +17,7 @@ whitelists = {} # {ff_owner_id: [white, listed, ids]} (Adding file usage later,
@hook.command("forcefield")
def on_forcefield_command(sender, args):
def on_forcefield_command(sender, command, label, args):
if not is_player(sender) or not sender.hasPermission(ff_perm):
noperm(sender)
return True
@@ -28,7 +29,7 @@ def on_forcefield_command(sender, args):
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)
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.
@@ -88,6 +89,7 @@ def change_whitelist(sender, add, names): #Add names if add == True else Remove
def whitelist_list(player):
try:
player_id = uid(player)
count = 0
forcefield_header(player, "&bForcefield whitelist:")
@@ -97,6 +99,8 @@ def whitelist_list(player):
msg(player, "&b %s. &f%s" % (count, pname))
if count == 0:
msg(player, "&c Your whitelist has no entries.")
except:
warn("Unable to finish whitelist_list process")
def whitelist_clear(player):
+6 -4
View File
@@ -1,3 +1,4 @@
import thread
from helpers import *
friends = open_json_file("friends", {}) # {Player_UUID:[List_of_friend_uuids]}
@@ -25,6 +26,7 @@ def friendmessage(player, message): # sends a message with a prefix
def ls(sender):
try:
sender_friends = friends.get(uid(sender), False)
if sender_friends:
friends_string = ""
@@ -33,14 +35,14 @@ def ls(sender):
friendmessage(sender, "&aYour friends list: " + friends_string[:len(friends_string)-2])
else:
friendmessage(sender, "&cYour friends list is empty")
except:
warn("Unable to finish friends' ls process")
def clear(sender):
sender_id = uid(sender)
if friends.get(sender_id, False):
for uuid in friends[sender_id]:
friendmessage(retrieve_player(uuid), "&c&o%s &cremoved you from their friends list" % stripcolors(sender.getDisplayName()))
friends.pop(sender_id)
friendmessage(sender, "&aFriends list cleared")
save_friends()
@@ -123,7 +125,7 @@ def fhelp(sender):
@hook.command("friends")
def on_friend_command(sender, args):
def on_friend_command(sender, command, label, args):
if not is_player(sender):
friendmessage(sender, "&c&lYou can't have friends!")
return True
@@ -133,7 +135,7 @@ def on_friend_command(sender, args):
# /friends list
if cmd in ["list", "lst", "*"]:
ls(sender)
thread.start_new_thread(ls, (sender,))
# /friends clear
elif cmd in ["clear", "/"]:
+43 -36
View File
@@ -7,6 +7,11 @@ import org.bukkit.Location as Location
import org.bukkit.entity.Player as Player
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause as TeleportCause
import org.bukkit.block as bblock
import org.bukkit.event.entity as entity
import org.bukkit.command.ConsoleCommandSender
from org.bukkit.entity import *
from traceback import format_exc as trace
shared = {} # this dict can be used to share stuff across modules
@@ -15,17 +20,32 @@ server = bukkit.Bukkit.getServer()
def info(text):
"""
Log info to console
"""
server.getLogger().info("[RedstonerUtils] %s" % text)
def warn(text):
"""
Log warning to console
"""
server.getLogger().warning("[RedstonerUtils] %s" % text)
def error(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):
"""
send a message to player
@@ -33,7 +53,7 @@ def msg(player, text, usecolor = True, basecolor = None):
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
"""
if player and (player == server.getConsoleSender() or player.getPlayer()): # getPlayer() returns None when offline
if player and (player == server.getConsoleSender() or player.isOnline()): # getPlayer() returns None when offline
if basecolor:
if usecolor:
text = colorify(text)
@@ -42,15 +62,16 @@ def msg(player, text, usecolor = True, basecolor = None):
player.sendMessage(colorify(text) if usecolor else text)
def broadcast(perm, 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)
for recipient in list(server.getOnlinePlayers()) + [server.getConsoleSender()]:
if not perm or recipient.hasPermission(perm):
msg(recipient, text)
msg(recipient, text, usecolor = False)
def colorify(text):
@@ -90,14 +111,20 @@ def plugin_header(recipient = None, name="Redstoner Utils"):
def noperm(player):
"""
Send the default permission failure message to the player
"""
msg(player, "&cno permission")
def runas(player, cmd):
"""
run a command as player
the cmd should no be prefixed with a /
the cmd should NOT be prefixed with a /
"""
if is_player(player):
player.chat("/" + cmd)
else:
server.dispatchCommand(player, cmd)
@@ -129,13 +156,6 @@ def checkargs(sender, args, amin, amax):
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):
"""
returns True if the player is in Creative mode
@@ -167,24 +187,23 @@ def known_player(player):
return player.hasPlayedBefore()
def open_json_file(filename, default):
def open_json_file(filename, default = None):
"""
opens the given json file and returns an object or returns None on error
filename is the path + name of the file.
filename is only the name of the file without .json appended.
"""
data = None
try:
with open("plugins/redstoner-utils.py.dir/files/%s.json" % filename) as obj:
data = json_loads(obj.read())
default = json_loads(obj.read())
except Exception, e:
error("Failed to read from %s: %s" % (filename, e))
return (default if data is None else data)
return default
def save_json_file(filename, obj):
"""
saves the given object as json into filename
filename is the path + name of the file.
filename is only the name of the file without .json appended.
"""
try:
with open("plugins/redstoner-utils.py.dir/files/%s.json" % filename, "w") as f:
@@ -193,27 +212,15 @@ def save_json_file(filename, obj):
error("Failed to write to %s: %s" % (filename, e))
def toggle(player, ls, add = None, on = "&aToggle now on!", off = "&cToggle now off!", already = "&cToggle was already %s"):
def toggle(player, ls, name = "Toggle", add = None):
"""
Toggle presence of a player's UUID in a list (ls)
'add' controls if a player should be added(True) or removed(False)
if 'add' is None, ls will simply be toggled for that player.
when 'add' is given, but won't change anything, %s in 'already' is replaced with "ON" or "OFF"
Toggles presence of a player's UUID in a list
If add is given, True explicitely adds it whereas False removes it
"""
pid = uid(player)
enabled = pid in ls
# Do some checks and remove pid.
if enabled and add == False:
if pid in ls or add == False:
ls.remove(pid)
msg(player, on)
# Do some checks and append pid.
elif not enabled and add == True:
msg(player, "&a%s turned off!" % name)
elif add != False:
ls.append(pid)
msg(player, off)
# Already on/off (optional)
else:
msg(player, already % (" ON" if add else " OFF"))
msg(player, "&a%s turned on!" % name)
+32
View File
@@ -0,0 +1,32 @@
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
+1 -1
View File
@@ -37,7 +37,7 @@ def tp_chunk(sender, id):
@hook.command("lagchunks")
def on_lagchunks_command(sender, args):
def on_lagchunks_command(sender, command, label, args):
if sender.hasPermission("utils.lagchunks"):
plugin_header(sender, "Lagchunks")
global lagchunks
+211
View File
@@ -0,0 +1,211 @@
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"]
logging_in = {}
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))
if crypt.verify(password, hashed):
if user.getName() in logging_in:
del logging_in[user.getName()]
msg(user, "&aLogged in successfully!")
else:
if user.getName() in 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):
if sender.getName() in 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):
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):
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):
if sender.getName() in logging_in:
return "&cYou are not logged in"
if not is_registered(uid(sender)):
return "&cYou are not registered!"
if not sender.getName() in logging_in:
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>",
description = "Removes password of <user> and sends them a notification",
helpNoargs = True)
def rmotherpass_command(sender, command, label, args):
if sender.getName() in 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", "high")
def on_join(event):
user = event.getPlayer()
if is_registered(uid(user)):
msg(event.getPlayer(), "&6You will be disconnected after 60 seconds if you don't &alogin")
msg(user, "&cUse /login <password>")
logging_in[user.getName()] = time.time()
@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 name, jointime in logging_in.iteritems():
if now - jointime > wait_time:
player = server.getPlayer(name)
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 = event.getPlayer()
if user.getName() in logging_in:
event.setCancelled(True)
+38 -3
View File
@@ -9,13 +9,12 @@ 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']
try:
# Library that adds a bunch of re-usable methods which are used in nearly all other modules
from helpers import *
except:
print("[RedstonerUtils] ERROR: Failed to import helpers:")
print(print_traceback())
@hook.enable
def on_enable():
info("RedstonerUtils enabled!")
@@ -31,20 +30,56 @@ info("Loading RedstonerUtils...")
# Import all modules, in this order
shared["load_modules"] = [
# Collection of tiny utilities
"misc",
# Adds chat for staff using /ac <text or ,<text>
"adminchat",
# Adds /badge, allows to give players achievements
"badges",
# Adds a few block placement corrections/mods
"blockplacemods",
# Adds /calc, toggles automatic solving of Math expressions in chat
"calc",
# Plugin to locate laggy chunks. /lc <n> lists chunks with more than n entities
"lagchunks",
# 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",
# 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",
"friends"
# 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 /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
"playermanager",
# Plots
"plotter"
]
shared["modules"] = {}
for module in shared["load_modules"]:
+13 -7
View File
@@ -52,7 +52,7 @@ def onChat(event):
except:
# list might not be mutable, ignoring. Receiver will get the message twice
pass
message = " ".join([sender.getDisplayName(), arrow] + rec_words)
message = " "+" ".join([sender.getDisplayName(), arrow] + rec_words)
msg(recipient, message, usecolor = False)
recipient.playSound(recipient.getLocation(), "mob.chicken.plop", 1, 2)
@@ -86,7 +86,7 @@ def add_keyword(sender, args):
if keywords:
mentions[uid(sender)] = keywords
msg(sender, "&aYou are now listening for '&2%s'!" % new_word)
msg(sender, "&aYou are now listening for '&2%s&2'!" % new_word)
saveMentions()
return True
@@ -107,13 +107,19 @@ def del_keyword(sender, args):
elif sender_id in mentions:
del mentions[sender_id]
saveMentions()
msg(sender, "&aYou are no longer listening for '&2%s&e'!" % del_word)
msg(sender, "&aYou are no longer listening for '&2%s&2'!" % del_word)
else:
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")
def onListenCommand(sender, args):
def onListenCommand(sender, command, label, args):
plugin_header(sender, "Mentio")
argnum = len(args)
@@ -137,7 +143,7 @@ def onListenCommand(sender, args):
if not keywords:
msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>")
else:
msg(sender, "&a/mentio add <word>")
msg(sender, "&a/mentio del <word>")
msg(sender, "&a/mentio list")
show_help(sender)
else:
show_help(sender)
return True
+189 -83
View File
@@ -1,128 +1,189 @@
#pylint: disable = F0401
from helpers import *
from time import time as now
from time import sleep
from sys import exc_info
import thread
import org.bukkit.inventory.ItemStack as ItemStack
import org.bukkit.Bukkit as Bukkit
from basecommands import simplecommand
#
# Welcome new players
#
@hook.event("player.PlayerJoinEvent", "monitor")
def on_join(event):
"""
Welcome new players
"""
player = event.getPlayer()
# send welcome broadcast
if not player.hasPlayedBefore():
broadcast("utils.greet_new", "")
broadcast("utils.greet_new", "&a&lPlease welcome &f" + player.getDisplayName() + " &a&lto Redstoner!")
broadcast("utils.greet_new", "")
broadcast("utils.greet_new", "\n&a&lPlease welcome &f" + player.getDisplayName() + " &a&lto Redstoner!\n")
# clear out some eventual crap before
msg(player, " \n \n \n \n \n \n \n \n \n \n \n \n ")
msg(player, " &4Welcome to the Redstoner Server!")
msg(player, " &6Before you ask us things, take a quick")
msg(player, " &6look at the &a&l/FAQ &6command.")
msg(player, " &6look at &a&nredstoner.com/info")
msg(player, " \n&6thank you and happy playing ;)")
msg(player, " \n \n")
# teleport to spawn when spawning inside portal
loginloc = player.getLocation().getBlock().getType()
headloc = player.getEyeLocation().getBlock().getType()
if str(loginloc) == "PORTAL" or str(headloc) == "PORTAL":
if "PORTAL" in [str(headloc), str(loginloc)]:
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")
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)
#
# /sudo - execute command/chat *as* a player/console
#
Keep in mind that, on "lowest" priority, PlotMe might cancel events.
@hook.command("sudo")
def on_sudo_command(sender, args):
if sender.hasPermission("utils.sudo"):
plugin_header(sender, "Sudo")
if not checkargs(sender, args, 2, -1):
"""
dup = 0 #Used to store when someone used //up
@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:]))
""" Disabled while builder can't access Trusted
@hook.event("player.PlayerGameModeChangeEvent", "low")
def on_gamemode(event):
user = event.getPlayer()
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"))
@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]
cmd = " ".join(args[1:])
msg(sender, "Running '&e%s&r' as &3%s" % (cmd, target))
if cmd[0] == "/":
cmd = cmd[1:]
if target.lower() == "server" or target.lower() == "console":
runas(server.getConsoleSender(), cmd)
elif server.getPlayer(target):
runas(server.getPlayer(target), cmd)
else:
msg(sender, "&cPlayer %s not found!" % target)
else:
if target.lower() == "server" or target.lower() == "console":
runas(server.getConsoleSender(), "say %s" % cmd)
elif server.getPlayer(target):
server.getPlayer(target).chat(cmd)
else:
msg(sender, "&cPlayer %s not found!" % target)
else:
noperm(sender)
return True
msg(sender, "&2[SUDO] &rRunning '&e%s&r' as &3%s" % (cmd, target))
is_cmd = cmd[0] == "/"
is_console = target.lower() in ["server", "console"]
if is_console:
server.dispatchCommand(server.getConsoleSender(), cmd[1:] if is_cmd else cmd)
return None
target_player = server.getPlayer(target)
if target_player:
target_player.chat(cmd)
return None
return "&cPlayer %s not found!" % target
#
# Clicking redstone_sheep with shears will drop redstone + wool and makes a moo sound
#
last_shear = 0.0
@hook.event("player.PlayerInteractEntityEvent")
def on_player_entity_interact(event):
global last_shear
if not event.isCancelled():
shear_time = now()
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)
@simplecommand("me",
usage = "[message..]",
description = "Sends a message in third person",
helpNoargs = True)
def on_me_command(sender, command, label, args):
text = colorify("&7- %s &7%s " % (sender.getDisplayName() if isinstance(sender, Player) else "&9CONSOLE", u"\u21E6"))
broadcast("utils.me", text + " ".join(args), usecolor = sender.hasPermission("essentials.chat.color"))
return None
#
# /pluginversions - print all plugins + versions; useful when updating plugins
#
@hook.command("pluginversions")
def on_pluginversions_command(sender, args):
def on_pluginversions_command(sender, command, label, args):
"""
/pluginversions
print all plugins + versions; useful when updating plugins
"""
try:
plugin_header(sender, "Plugin versions")
plugins = list(server.getPluginManager().getPlugins())
plugins = [pl.getDescription() for pl in list(ArrayList(java_array_to_list(server.getPluginManager().getPlugins())))]
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" + plugin.getDescription().getName() + "&r: &e" + plugin.getDescription().getVersion())
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")
def on_echo_command(sender, args):
def on_echo_command(sender, command, label, args):
"""
/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):
"""
/pyeval
run python ingame
"""
try:
result = eval(code)
msg(sender, ">>> %s: %s" % (colorify("&3") + type(result).__name__, colorify("&a") + unicode(result) + "\n "), usecolor = False)
@@ -135,22 +196,67 @@ def eval_thread(sender, code):
msg(sender, ">>> %s: %s" % (eclass.__name__, e) + "\n ", False, "c")
thread.exit()
@hook.command("pyeval")
def on_pyeval_command(sender, args):
if sender.hasPermission("utils.pyeval"):
if not checkargs(sender, args, 1, -1):
return True
msg(sender, "%s" % " ".join(args), False, "e")
@simplecommand("pyeval",
usage = "[code..]",
description = "Runs python [code..] and returns the result",
helpNoargs = True)
def on_pyeval_command(sender, command, label, args):
msg(sender, " ".join(args), False, "e")
thread.start_new_thread(eval_thread, (sender, " ".join(args)))
return None
@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:
noperm(sender)
return True
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")
def on_modules_command(sender, args):
def on_modules_command(sender, command, label, args):
"""
/modules
list all modules, unloaded modules in red
"""
plugin_header(sender, "Modules")
for mod in shared["load_modules"]:
color = "a" if mod in shared["modules"] else "c"
msg(sender, "&" + color + mod)
msg(sender, ", ".join([(("&a" if mod in shared["modules"] else "&c") + mod) for mod in shared["load_modules"]]))
""" 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]
"""
+2 -2
View File
@@ -5,13 +5,13 @@ default_motd = colorify(server.getMotd())
motd = default_motd
@hook.command("getmotd")
def on_getmotd_command(sender, args):
def on_getmotd_command(sender, command, label, args):
plugin_header(sender, "MOTD")
msg(sender, motd, usecolor = False)
@hook.command("setmotd")
def on_setmotd_command(sender, args):
def on_setmotd_command(sender, command, label, args):
global motd
if sender.hasPermission("utils.setmotd"):
if not checkargs(sender, args, 1, -1):
+5
View File
@@ -1,4 +1,9 @@
#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.io.File
import java.net.URL
+27
View File
@@ -0,0 +1,27 @@
from helpers import *
players = []
class py_player:
def __init__(player):
self.player = player
#Properties TODO
#Example:
self.logging_in = False
def get_py_player(player):
py_player = players[players.index(player)]
return py_player
@hook.event("player.PlayerJoinEvent","highest")
def on_join(event):
player = py_player(event.getPlayer())
players.append(player)
@hook.event("player.PlayerQuitEvent","highest")
def on_leave(event):
players.remove(get_py_player(event.getPlayer()))
+192
View File
@@ -0,0 +1,192 @@
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
+49 -23
View File
@@ -1,28 +1,54 @@
#!/usr/bin/python
# this was going to be a PlotMe-like plugin "plotter"
# but it seems like PlotMe is still beeing developed, so we don't need our own.
"""
*Very basic* start of a custom plot-plugin like PlotMe
on hold because the PlotMe developer continued to develop PlotMe
"""
import sys
x_plot_size = 3
z_plot_size = 3
padding = 1
def base_coords(x, z):
pid = plot_id(x, z)
return [pid[0] * (x_plot_size + padding), pid[1] * (z_plot_size + padding)]
def bounds(x, z):
base = base_coords(x, z)
return [base, [base[0] + x_plot_size, base[1] + z_plot_size]]
def plot_id(x, z):
return [x // (x_plot_size + padding), z // (z_plot_size + padding)]
from helpers import *
from basecommands import simplecommand
x = int(sys.argv[1])
z = int(sys.argv[2])
print "id: %s" % plot_id(x, z)
print "base: %s" % base_coords(x, z)
print "bounds: %s" % bounds(x, z)
@simplecommand("plotter",
aliases = ["pt"],
senderLimit = 0,
description = "Plot commands")
def plotter_command(sender, command, label, args):
loc = sender.getLocation()
x = loc.getX()
z = loc.getZ()
plot = Plot.get(x, z)
if plot:
msg(sender, "id: %s" % [plot.idx, plot.idz])
msg(sender, "bottom: %s" % [plot.bottomx, plot.bottomz])
msg(sender, "top: %s" % [plot.topx, plot.topz])
else:
msg(sender, "&cThis is not a plot.")
class Plot:
plot_size = 20
padding = 3
padded_size = plot_size + padding
def __init__(self, x, z):
x = int(x)
z = int(z)
self.idx = x
self.idz = z
self.bottomx = x * self.padded_size
self.bottomz = z * self.padded_size
self.topx = self.bottomx + self.plot_size
self.topz = self.bottomz + self.plot_size
@staticmethod
def is_border(x, z):
xborder = Plot.plot_size < x % Plot.padded_size < Plot.padded_size
zborder = Plot.plot_size < z % Plot.padded_size < Plot.padded_size
return xborder or zborder
@staticmethod
def get(x, z):
idx = x // Plot.padded_size
idz = z // Plot.padded_size
return None if Plot.is_border(x, z) else Plot(idx, idz)
+2 -1
View File
@@ -1,4 +1,5 @@
name: RedstonerUtils
main: main.py
version: 3.0.0
version: 3.1.0
author: redstone_sheep
+53
View File
@@ -0,0 +1,53 @@
from helpers import *
import org.bukkit.Bukkit as Bukkit
from java.util.UUID import fromString as juuid
toggle_dict = {}
permission = "utils.pmtoggle"
@hook.command("tm")
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())
+88 -27
View File
@@ -2,6 +2,7 @@ from helpers import *
from java.util.UUID import fromString as juuid
import time
import thread
from traceback import format_exc as trace
time_format = "%Y.%m.%d %H:%M"
@@ -13,42 +14,83 @@ rp_permission = "utils.rp"
def print_help(sender):
msg(sender, " &2/report <text> &eReport something")
msg(sender, " &2/rp list &eList unresolved reports (id, player, text)")
msg(sender, " &2/rp open &eList open 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 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):
def print_list(sender, closed):
try: # new thread, anything can happen.
msg(sender, "&a" + str(len(reports)) + " reports:")
for i, report in enumerate(reports):
name = server.getOfflinePlayer(juuid(report["uuid"])).getName()
msg(sender, "&8[&e%s&c%s&8] &3%s&f: &a%s" % (i, report["time"], name, report["msg"]))
targeted_reports = dict(enumerate(reports))
for i in list(targeted_reports):
report = targeted_reports[i]
if report["closed"] != closed:
targeted_reports.pop(i)
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):
if rep_id >= len(reports) or rep_id < 0:
msg(sender, "&cReport &3#" + str(rep_id) + "&c does not exist!")
return True
else:
report = reports[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 )
msg(sender, "&aTeleported to %s&areport #%s" % ("&cclosed " if report["closed"] else "", 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):
if len(reports) > rep_id >= 0:
report = reports[rep_id]
reports.pop(rep_id)
if not sender.hasPermission(rp_permission + ".del"):
noperm(sender)
return
action = "&cdeleted"
report = edit_report(sender, rep_id)
if report != None:
reports.remove(report)
save_reports()
msg(sender, "&aReport #%s deleted." % rep_id)
reporter = server.getOfflinePlayer(juuid(report["uuid"]))
plugin_header(reporter, "Report")
msg(reporter, "&aReport '&e%s&a' was resolved by %s." % (report["msg"], sender.getName()))
else:
msg(sender, "&aReport #%s %s" % (rep_id, action))
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!")
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():
@@ -56,13 +98,16 @@ def save_reports():
@hook.command("rp")
def on_rp_command(sender, args):
def on_rp_command(sender, command, label, args):
if sender.hasPermission(rp_permission):
plugin_header(sender, "Reports")
if len(args) > 0:
if args[0] == "list":
subcmd = args[0].lower()
if subcmd == "closed":
# needs to run in seperate thread because of getOfflinePlayer
thread.start_new_thread(print_list, (sender))
thread.start_new_thread(print_list, (sender, True,))
elif subcmd in ["open", "list"]:
thread.start_new_thread(print_list, (sender, False,))
else:
if not checkargs(sender, args, 2, 2):
return True
@@ -72,13 +117,17 @@ def on_rp_command(sender, args):
msg(sender, "&cDoesn't look like &3" + args[1] + "&c is a valid number!")
print_help(sender)
return True
if args[0] == "tp":
if subcmd == "tp":
if not is_player(sender):
msg(sender, "&conly players can do this")
return True
tp_report(sender, repid)
elif args[0] == "del":
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:
@@ -89,7 +138,7 @@ def on_rp_command(sender, args):
@hook.command("report")
def on_report_command(sender, args):
def on_report_command(sender, command, label, args):
plugin_header(sender, "Report")
if not is_player(sender):
msg(sender, "&conly players can do this")
@@ -109,7 +158,8 @@ def on_report_command(sender, args):
"yaw": int(loc.yaw),
"pitch": int(loc.pitch),
"world": loc.getWorld().name,
"time": time.strftime(time_format)
"time": time.strftime(time_format),
"closed": False
}
reports.append(report)
save_reports()
@@ -125,9 +175,9 @@ def reports_reminder(): # needs 2 args for unknown reason
if not check_reports:
info("Reports reminder thread killed.")
thread.exit()
if len(reports) > 0:
broadcast(rp_permission, "&2--=[ Reports ]=--")
broadcast(rp_permission, "&aThere are %s pending reports!" % len(reports))
targeted_reports = get_reports(False)
if len(targeted_reports) > 0:
broadcast(rp_permission, "&aThere are %s open reports!" % len(targeted_reports))
def stop_reporting():
@@ -136,4 +186,15 @@ def stop_reporting():
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, ())
+3 -4
View File
@@ -30,10 +30,8 @@ def print_lol(sender, lid):
broadcast(None, "&8[&blol&8] &7%s&8: &e%s" % (dispname, lols[lid]))
last_msg = time()
else:
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)))
@@ -41,15 +39,16 @@ def search_lols(sender, keyword):
if not keyword:
msg(sender, "&cPlease provide a keyword to search for!")
return
keyword = keyword.lower()
msg(sender, "&aLols containing '&6%s&a':" % keyword)
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, "") # empty line showing end of list
@hook.command("lol")
def on_lol_command(sender, args):
def on_lol_command(sender, command, label, args):
plugin_header(sender, "SayLol")
cmd = args[0] if len(args) > 0 else None
+3
View File
@@ -0,0 +1,3 @@
mysql_database = "jdbc:mysql://localhost/database"
mysql_user = "username"
mysql_pass = "secret"
+969
View File
@@ -0,0 +1,969 @@
#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", "high")
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
+7 -1
View File
@@ -1,3 +1,9 @@
"""
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.PacketPlayOutNamedEntitySpawn as PacketPlayOutNamedEntitySpawn
import net.minecraft.server.v1_7_R1.PlayerInteractManager as PlayerInteractManager
@@ -32,7 +38,7 @@ def spawn(dispname, sender, x, y, z):
@hook.command("spawnplayer")
def on_spawnplayer_command(sender, args):
def on_spawnplayer_command(sender, command, label, args):
global amount, row, ground, goup
# X and Z position
+60
View File
@@ -0,0 +1,60 @@
from helpers import *
from secrets import *
import mysqlhack
from com.ziclix.python.sql import zxJDBC
ranks = {
"member" : 3,
"builder" : 7,
"trusted" : 8,
"helper" : 9,
"trainingmod" : 10,
"mod" : 4,
"admin" : 5
}
@hook.event("player.PlayerJoinEvent", "normal")
def on_player_join(event):
user = event.getPlayer()
uuid = uid(player).replace("-", "")
role = get_role(uuid)
if role in [1, 2, 6]: #Disabled/Banned/Superadmin
return
if role:
for rank in ranks:
if user.hasPermission("group." + rank):
if role != ranks[rank]:
set_role(uuid, ranks[rank])
return
if not user.hasPlayedBefore():
return
if role == None:
msg(user, "&cYou haven't registed yet! Make sure to do so on redstoner.com")
def get_role(uuid):
return execute_query("SELECT `role_id` FROM users WHERE `uuid` = ? LIMIT 1", uuid)[0][17]
def set_role(uuid, role_id):
execute_update("UPDATE users SET `role_id` = %d WHERE `uuid` = ?" % role_id, uuid)
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,))
curs.close()
conn.close()
+3
View File
@@ -1,4 +1,7 @@
#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.BlockBreakEvent as BlockBreakEvent
import org.bukkit.event.player.PlayerInteractEvent as PlayerInteractEvent
-4
View File
@@ -1,4 +0,0 @@
import glob
tools = []
for module_name in glob.glob("plugins/redstoner-utils.py.dir/toolbox/*.py"):
tools.append(__import__(module_name))
-42
View File
@@ -1,42 +0,0 @@
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)
+2 -2
View File
@@ -99,13 +99,13 @@ def tokengen_command(sender, args):
@hook.command("token")
def on_token_command(sender, args):
def on_token_command(sender, command, label, args):
thread.start_new_thread(token_command, (sender,))
return True
@hook.command("gettoken")
def on_gettoken_command(sender, args):
def on_gettoken_command(sender, command, label, args):
thread.start_new_thread(tokengen_command, (sender, args))
return True