diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/Vagrantfile b/Vagrantfile index 173c6c2..809097e 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -12,8 +12,9 @@ Vagrant.configure('2') do |config| end - # Make minecraft server port available on hosting machine - # config.vm.network :forwarded_port, host: 25565, guest: 25565 + # Make minecraft server port available on hosting machine, as localhost + config.vm.network :forwarded_port, host: 25565, guest: 25565 + # Make minecraft server port available on remote machines, through real ip address config.vm.network 'public_network' config.vm.provision :shell, :path => 'bin/vagrant.sh' diff --git a/lib/Minecraft.jar b/lib/Minecraft.jar new file mode 100644 index 0000000..1f331a9 Binary files /dev/null and b/lib/Minecraft.jar differ diff --git a/server/.gitignore b/server/.gitignore deleted file mode 100644 index 2f20317..0000000 --- a/server/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore everything -* -!*/ -# Except for.. -!.gitignore -!config/worlds/default/default_NORMAL.cfg -!config/server.cfg -!run-server.sh -!plugins/scriptcraft.jar \ No newline at end of file diff --git a/server/config/db.cfg b/server/config/db.cfg new file mode 100755 index 0000000..85c80bd --- /dev/null +++ b/server/config/db.cfg @@ -0,0 +1,48 @@ +;#For more settings explanations see following websites ... +;#http://javatech.org/2007/11/c3p0-connectionpool-configuration-rules-of-thumb/ +;#https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool?_sscc=t +name=canarymod +host=localhost +username=admin +password=admin +port=3306 +maxConnections=5 +;Determines how many connections at a time c3p0 will try to acquire when the pool is exhausted. +acquire-increment=5 +;Determines how long idle connections can stay in the connection pool before they are removed. +max-connection-idle-time=900 +;Time until the connection pool will be culled down to min-connection-pool-size. Set 0 to not enforce pool shrinking. +max-excess-connections-idle-time=1800 +;The maximum allowed number of pooled connections. More for larger servers +max-connection-pool-size=10 +;The minimum amount of connections allowed. More means more memory usage but takes away some impact from creating new connections. +min-connection-pool-size=3 +;Amount of threads that will perform slow JDBC operations (closing idle connections, returning connections to pool etc) +num-helper-threads=4 +;Defines a time a connection can remain checked out. After that it will be forced back into the connection pool. +return-connection-timeout=900 +connection-test-frequency=0 +;Number of max cached statements on all connections. (Roughly 5 * expected pooled connections) +max-cached-statements=50 +;Number of max cached statements on a single connection. +max-statements-per-connection=5 +;Number of threads to use when closing statements is deferred (happens when parent connection is still in use) +statement-cache-close-threads=1 +;The name to use for the Bans table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +bans-table-name=ban +;The name to use for the Groups table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +groups-table-name=group +;The name to use for the Kits table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +kits-table-name=kit +;The name to use for the Operators table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +operators-table-name=operators +;The name to use for the Permissions table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +permissions-table-name=permission +;The name to use for the Permissions table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +players-table-name=player +;The name to use for the ReserveList table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +reservelist-table-name=reservelist +;The name to use for the Warps table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +warps-table-name=warp +;The name to use for the WhiteList table. NOTE: Changing this here will require you to manually change the name of the table in the database (if present) +whitelist-table-name=whitelist diff --git a/server/config/metrics.cfg b/server/config/metrics.cfg new file mode 100755 index 0000000..97f8058 --- /dev/null +++ b/server/config/metrics.cfg @@ -0,0 +1,5 @@ +#http://mcstats.org +#Fri Aug 14 11:39:22 BST 2015 +debug=false +guid=880c13fb-cc6f-424b-b9b1-2d30cd96d2e5 +opt-out=false diff --git a/server/config/motd.txt b/server/config/motd.txt new file mode 100755 index 0000000..05bf0c4 --- /dev/null +++ b/server/config/motd.txt @@ -0,0 +1,7 @@ +# (Login) Message of the Day +# See forums thread http://canarymod.net/forum/canarymod-board/discussions/motd-variables-3447 +# for the list of default variables +# or the plugins threads that add-on to the Message Of The Day +# Lines may be prefixed with {permissions:<[node] or ![node] or [node]&[node]&![node]>} +# Examples: {permissions:canary.super.administor} {permissions:canary.world.build&!canary.super.administrator} +# # # # # diff --git a/server/config/ops.cfg b/server/config/ops.cfg new file mode 100755 index 0000000..3465040 --- /dev/null +++ b/server/config/ops.cfg @@ -0,0 +1,5 @@ +# Note: This file is not guaranteed to be synchronous with the actual ops list in database. +# However, you may use it to quickly add new operators as you please. +# Any duplicate entries will be taken care of so don't worry. +# Lines starting with # are comments ;) +# Add one name to each line. diff --git a/server/config/plugin_priorities.cfg b/server/config/plugin_priorities.cfg new file mode 100755 index 0000000..b1eced6 --- /dev/null +++ b/server/config/plugin_priorities.cfg @@ -0,0 +1 @@ +ScriptCraft=10 diff --git a/server/config/server.cfg b/server/config/server.cfg old mode 100644 new mode 100755 index ed7b1dd..5a1a2ac --- a/server/config/server.cfg +++ b/server/config/server.cfg @@ -26,7 +26,7 @@ date-format=yyyy.MM.dd, hh:mm:ss ;Sets whether to send player death message or not death-messages=true ;Name of the default loaded world -default-world-name=default +default-world-name=Roshar ;This sets the maximum possible size in blocks, expressed as a radius, that the world border can obtain. default-world-size=29999984 ;Enables kicking players who are floating too long. @@ -46,7 +46,7 @@ motd=CanaryMod Minecraft Server network-compression-threshold=256 ;Sets whether to authenticate connecting users. ;WARNING: Setting to false is INSECURE and should not be done in a production environment. -online-mode=true +online-mode=false ;Timeout in minutes before kicking an idle player player-idle-timeout=60 ;Sets whether to send data to clients for the Player List diff --git a/server/config/worlds/Roshar/Roshar_END.cfg b/server/config/worlds/Roshar/Roshar_END.cfg new file mode 100755 index 0000000..6aabf59 --- /dev/null +++ b/server/config/worlds/Roshar/Roshar_END.cfg @@ -0,0 +1,31 @@ +world-name=Roshar_END +world-type=DEFAULT +spawn-protection=16 +max-build-height=256 +generate-structures=true +generator-settings= +world-seed= +startup-autoload=false +warp-autoload=false +allow-nether=true +allow-end=true +allow-flight=true +pvp=true +difficulty=1 +gamemode=1 +forceDefaultGameMode=true +forceDefaultGameModeDimensional=false +auto-heal=default +enable-experience=true +enable-health=true +spawn-villagers=true +spawn-golems=true +spawn-animals=true +spawn-monsters=true +natural-animals=Bat,Chicken,Cow,Mooshroom,Ocelot,Pig,Sheep,Wolf,Horse,Rabbit +natural-monsters=Enderman,PigZombie,Blaze,CaveSpider,Creeper,Ghast,MagamaCube,Silverfish,Skeleton,Slime,Spider,Witch,Zombie,Wither,EnderDragon,GiantZombie,Endermite,Guardian +natural-golems=IronGolem,Snowman +natural-wateranimals=Squid +natural-spawn-rate=100 +ender-blocks=2,3,12,13,37,38,39,40,46,81,82,86,103,110 +disallowed-blocks=7,8,9,10,11,46,51,52 diff --git a/server/config/worlds/Roshar/Roshar_NETHER.cfg b/server/config/worlds/Roshar/Roshar_NETHER.cfg new file mode 100755 index 0000000..82c04a0 --- /dev/null +++ b/server/config/worlds/Roshar/Roshar_NETHER.cfg @@ -0,0 +1,31 @@ +world-name=Roshar_NETHER +world-type=DEFAULT +spawn-protection=16 +max-build-height=256 +generate-structures=true +generator-settings= +world-seed= +startup-autoload=false +warp-autoload=false +allow-nether=true +allow-end=true +allow-flight=true +pvp=true +difficulty=1 +gamemode=1 +forceDefaultGameMode=true +forceDefaultGameModeDimensional=false +auto-heal=default +enable-experience=true +enable-health=true +spawn-villagers=true +spawn-golems=true +spawn-animals=true +spawn-monsters=true +natural-animals=Bat,Chicken,Cow,Mooshroom,Ocelot,Pig,Sheep,Wolf,Horse,Rabbit +natural-monsters=Enderman,PigZombie,Blaze,CaveSpider,Creeper,Ghast,MagamaCube,Silverfish,Skeleton,Slime,Spider,Witch,Zombie,Wither,EnderDragon,GiantZombie,Endermite,Guardian +natural-golems=IronGolem,Snowman +natural-wateranimals=Squid +natural-spawn-rate=100 +ender-blocks=2,3,12,13,37,38,39,40,46,81,82,86,103,110 +disallowed-blocks=7,8,9,10,11,46,51,52 diff --git a/server/config/worlds/Roshar/Roshar_NORMAL.cfg b/server/config/worlds/Roshar/Roshar_NORMAL.cfg new file mode 100755 index 0000000..68ebebb --- /dev/null +++ b/server/config/worlds/Roshar/Roshar_NORMAL.cfg @@ -0,0 +1,31 @@ +world-name=Roshar_NORMAL +world-type=DEFAULT +spawn-protection=16 +max-build-height=256 +generate-structures=true +generator-settings= +world-seed=-3597413500116427194 +startup-autoload=false +warp-autoload=false +allow-nether=true +allow-end=true +allow-flight=true +pvp=true +difficulty=1 +gamemode=1 +forceDefaultGameMode=true +forceDefaultGameModeDimensional=false +auto-heal=default +enable-experience=true +enable-health=true +spawn-villagers=true +spawn-golems=true +spawn-animals=true +spawn-monsters=true +natural-animals=Bat,Chicken,Cow,Mooshroom,Ocelot,Pig,Sheep,Wolf,Horse,Rabbit +natural-monsters=Enderman,PigZombie,Blaze,CaveSpider,Creeper,Ghast,MagamaCube,Silverfish,Skeleton,Slime,Spider,Witch,Zombie,Wither,EnderDragon,GiantZombie,Endermite,Guardian +natural-golems=IronGolem,Snowman +natural-wateranimals=Squid +natural-spawn-rate=100 +ender-blocks=2,3,12,13,37,38,39,40,46,81,82,86,103,110 +disallowed-blocks=7,8,9,10,11,46,51,52 diff --git a/server/config/worlds/default/Roshar/Roshar_NORMAL.cfg b/server/config/worlds/default/Roshar/Roshar_NORMAL.cfg new file mode 100755 index 0000000..a758e83 --- /dev/null +++ b/server/config/worlds/default/Roshar/Roshar_NORMAL.cfg @@ -0,0 +1,31 @@ +world-name=Roshar_NORMAL +world-type=DEFAULT +spawn-protection=16 +max-build-height=256 +generate-structures=true +generator-settings= +world-seed= +startup-autoload=false +warp-autoload=false +allow-nether=true +allow-end=true +allow-flight=true +pvp=true +difficulty=1 +gamemode=1 +forceDefaultGameMode=true +forceDefaultGameModeDimensional=false +auto-heal=default +enable-experience=true +enable-health=true +spawn-villagers=true +spawn-golems=true +spawn-animals=true +spawn-monsters=true +natural-animals=Bat,Chicken,Cow,Mooshroom,Ocelot,Pig,Sheep,Wolf,Horse,Rabbit +natural-monsters=Enderman,PigZombie,Blaze,CaveSpider,Creeper,Ghast,MagamaCube,Silverfish,Skeleton,Slime,Spider,Witch,Zombie,Wither,EnderDragon,GiantZombie,Endermite,Guardian +natural-golems=IronGolem,Snowman +natural-wateranimals=Squid +natural-spawn-rate=100 +ender-blocks=2,3,12,13,37,38,39,40,46,81,82,86,103,110 +disallowed-blocks=7,8,9,10,11,46,51,52 diff --git a/server/config/worlds/default/default_NORMAL.cfg b/server/config/worlds/default/default_NORMAL.cfg old mode 100644 new mode 100755 diff --git a/server/crash-reports/crash-2015-09-12_13.29.02-server.txt b/server/crash-reports/crash-2015-09-12_13.29.02-server.txt new file mode 100644 index 0000000..6b8b299 --- /dev/null +++ b/server/crash-reports/crash-2015-09-12_13.29.02-server.txt @@ -0,0 +1,84 @@ +---- Minecraft Crash Report ---- +// Would you like a cupcake? + +Time: 9/12/15 1:29 PM +Description: Ticking entity + +java.util.ConcurrentModificationException + at java.util.HashMap$HashIterator.nextEntry(HashMap.java:922) + at java.util.HashMap$KeyIterator.next(HashMap.java:956) + at net.minecraft.entity.EntityTracker.a(EntityTracker.java:308) + at net.minecraft.entity.player.EntityPlayerMP.s_(EntityPlayerMP.java:347) + at net.minecraft.world.World.a(World.java:1329) + at net.minecraft.world.WorldServer.a(WorldServer.java:614) + at net.minecraft.world.World.g(World.java:1309) + at net.minecraft.world.World.i(World.java:1188) + at net.minecraft.world.WorldServer.i(WorldServer.java:481) + at net.minecraft.server.MinecraftServer.z(MinecraftServer.java:680) + at net.minecraft.server.dedicated.DedicatedServer.z(DedicatedServer.java:446) + at net.minecraft.server.MinecraftServer.y(MinecraftServer.java:589) + at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:491) + at java.lang.Thread.run(Thread.java:745) + + +A detailed walkthrough of the error, its code path and all known details is as follows: +--------------------------------------------------------------------------------------- + +-- Head -- +Stacktrace: + at java.util.HashMap$HashIterator.nextEntry(HashMap.java:922) + at java.util.HashMap$KeyIterator.next(HashMap.java:956) + at net.minecraft.entity.EntityTracker.a(EntityTracker.java:308) + at net.minecraft.entity.player.EntityPlayerMP.s_(EntityPlayerMP.java:347) + at net.minecraft.world.World.a(World.java:1329) + at net.minecraft.world.WorldServer.a(WorldServer.java:614) + at net.minecraft.world.World.g(World.java:1309) + +-- Entity being ticked -- +Details: + Entity Type: null (net.minecraft.entity.player.EntityPlayerMP) + Entity ID: 44563072 + Entity Name: johnd_7 + Entity's Exact location: 755.50, 5.00, -181.50 + Entity's Block location: 755.00,5.00,-182.00 - World: (755,5,-182), Chunk: (at 3,0,10 in 47,-12; contains blocks 752,0,-192 to 767,255,-177), Region: (1,-1; contains chunks 32,-32 to 63,-1, blocks 512,0,-512 to 1023,255,-1) + Entity's Momentum: 0.00, 0.25, 0.00 + Entity's Rider: ~~ERROR~~ NullPointerException: null + Entity's Vehicle: ~~ERROR~~ NullPointerException: null +Stacktrace: + at net.minecraft.world.World.i(World.java:1188) + at net.minecraft.world.WorldServer.i(WorldServer.java:481) + +-- Affected level -- +Details: + Level name: Roshar + All players: 4 total; [EntityPlayerMP['greghuc'/160, l='Roshar', x=763.76, y=6.15, z=-191.31], EntityPlayerMP['CreativeStirling'/161, l='Roshar', x=401.94, y=4.00, z=-168.55], EntityPlayerMP['EnquiryStirling'/10026249, l='Roshar', x=763.50, y=4.00, z=-185.50], EntityPlayerMP['johnd_7'/44563072, l='Roshar', x=755.50, y=5.00, z=-181.50]] + Chunk stats: ServerChunkCache: 1024 Drop: 0 + Level seed: -5138459056659394599 + Level generator: ID 01 - flat, ver 0. Features enabled: false + Level generator options: + Level spawn location: 759.00,4.00,-189.00 - World: (759,4,-189), Chunk: (at 7,0,3 in 47,-12; contains blocks 752,0,-192 to 767,255,-177), Region: (1,-1; contains chunks 32,-32 to 63,-1, blocks 512,0,-512 to 1023,255,-1) + Level time: 676901 game time, 10534 day time + Level dimension: 0 + Level storage version: 0x04ABD - Anvil + Level weather: Rain time: 1 (now: false), thunder time: 1 (now: false) + Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: true +Stacktrace: + at net.minecraft.server.MinecraftServer.z(MinecraftServer.java:680) + at net.minecraft.server.dedicated.DedicatedServer.z(DedicatedServer.java:446) + at net.minecraft.server.MinecraftServer.y(MinecraftServer.java:589) + at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:491) + at java.lang.Thread.run(Thread.java:745) + +-- System Details -- +Details: + Minecraft Version: 1.8 + Operating System: Linux (amd64) version 3.2.0-23-generic + Java Version: 1.7.0_79, Oracle Corporation + Java VM Version: OpenJDK 64-Bit Server VM (mixed mode), Oracle Corporation + Memory: 421623432 bytes (402 MB) / 687091712 bytes (655 MB) up to 1037959168 bytes (989 MB) + JVM Flags: 1 total; -Xmx1024M + IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0 + Profiler Position: N/A (disabled) + Player Count: 6 / 20; [EntityPlayerMP['WookieCushion'/291734, l='Roshar', x=30.57, y=103.40, z=15.34], EntityPlayerMP['EccentricGreg'/343527, l='Roshar', x=68.99, y=59.00, z=-20.03], EntityPlayerMP['greghuc'/160, l='Roshar', x=763.76, y=6.15, z=-191.31], EntityPlayerMP['CreativeStirling'/161, l='Roshar', x=401.94, y=4.00, z=-168.55], EntityPlayerMP['EnquiryStirling'/10026249, l='Roshar', x=763.50, y=4.00, z=-185.50], EntityPlayerMP['johnd_7'/44563072, l='Roshar', x=755.50, y=5.00, z=-181.50]] + Is Modded: Definitely; Server brand changed to 'CanaryMod' + Type: Dedicated Server (map_server.txt) \ No newline at end of file diff --git a/server/db/ban.xml b/server/db/ban.xml new file mode 100755 index 0000000..acecefa --- /dev/null +++ b/server/db/ban.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/server/db/group.xml b/server/db/group.xml new file mode 100755 index 0000000..fae7934 --- /dev/null +++ b/server/db/group.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + 1 + true + visitors + visitors + §7 + null + + + 2 + false + players + visitors + §F + null + + + 3 + false + mods + players + §E + null + + + 4 + false + admins + mods + §C + null + + diff --git a/server/db/kit.xml b/server/db/kit.xml new file mode 100755 index 0000000..3701db3 --- /dev/null +++ b/server/db/kit.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/server/db/operators.xml b/server/db/operators.xml new file mode 100755 index 0000000..f13ae30 --- /dev/null +++ b/server/db/operators.xml @@ -0,0 +1,38 @@ + + + + + + + 1 + 7adfda8e-7c82-4ee1-88e2-6d407ff93a21 + + + 2 + b8e2bb98-f74f-3373-a144-0107bca542b7 + + + 3 + 08d6ef60-f157-3a8e-a04f-6af73400697c + + + 4 + 2494bee9-581d-3809-90d8-0d199b81c0a9 + + + 5 + b9075e8f-4773-3d2e-a08c-64345403cc03 + + + 6 + 95cbd4c7-125d-3376-a580-bb7b4f09789b + + + 7 + 14801086-f435-35d3-973a-6fe8572874c9 + + + 8 + 28755a9a-d3ba-366a-8837-bbd63051e079 + + diff --git a/server/db/permission.xml b/server/db/permission.xml new file mode 100755 index 0000000..60a9e6b --- /dev/null +++ b/server/db/permission.xml @@ -0,0 +1,30 @@ + + + + + + + + + + 1 + admins + * + group + true + + + 2 + mods + canary.super.ignoreRestrictions + group + true + + + 3 + players + canary.world.build + group + true + + diff --git a/server/db/permission_Roshar_END.xml b/server/db/permission_Roshar_END.xml new file mode 100755 index 0000000..0f4cdad --- /dev/null +++ b/server/db/permission_Roshar_END.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/server/db/permission_Roshar_NETHER.xml b/server/db/permission_Roshar_NETHER.xml new file mode 100755 index 0000000..ca24717 --- /dev/null +++ b/server/db/permission_Roshar_NETHER.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/server/db/permission_Roshar_NORMAL.xml b/server/db/permission_Roshar_NORMAL.xml new file mode 100755 index 0000000..3ca7df7 --- /dev/null +++ b/server/db/permission_Roshar_NORMAL.xml @@ -0,0 +1,65 @@ + + + + + + + + + + 1 + 7adfda8e-7c82-4ee1-88e2-6d407ff93a21 + scriptcraft.evaluate + player + true + + + 2 + 86ff3a9f-958a-4c06-80e0-8e0b1468976e + scriptcraft.evaluate + player + true + + + 3 + b8e2bb98-f74f-3373-a144-0107bca542b7 + scriptcraft.evaluate + player + true + + + 4 + 08d6ef60-f157-3a8e-a04f-6af73400697c + scriptcraft.evaluate + player + true + + + 5 + 28755a9a-d3ba-366a-8837-bbd63051e079 + scriptcraft.evaluate + player + true + + + 6 + b9075e8f-4773-3d2e-a08c-64345403cc03 + scriptcraft.evaluate + player + true + + + 7 + 14801086-f435-35d3-973a-6fe8572874c9 + scriptcraft.evaluate + player + true + + + 8 + 2494bee9-581d-3809-90d8-0d199b81c0a9 + scriptcraft.evaluate + player + true + + diff --git a/server/db/permission_default_NORMAL.xml b/server/db/permission_default_NORMAL.xml new file mode 100755 index 0000000..b223f9d --- /dev/null +++ b/server/db/permission_default_NORMAL.xml @@ -0,0 +1,23 @@ + + + + + + + + + + 1 + 86ff3a9f-958a-4c06-80e0-8e0b1468976e + scriptcraft.evaluate + player + true + + + 2 + 7adfda8e-7c82-4ee1-88e2-6d407ff93a21 + scriptcraft.evaluate + player + true + + diff --git a/server/db/player.xml b/server/db/player.xml new file mode 100755 index 0000000..a42687d --- /dev/null +++ b/server/db/player.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + players + 1 + false + Bob the Builder + null + + 67ff82f3-39b4-31a3-9589-10be5b915275 + + + mods + 2 + false + Moderator Person + null + + abbbd6eb-a0e6-342c-b1d2-c6f089b13499 + + + admins + 3 + false + Evil Uber Administrator + null + + d1c458d5-063a-3bf6-b6fb-87082abc5d37 + + + visitors + 4 + false + greghuc + null + + 86ff3a9f-958a-4c06-80e0-8e0b1468976e + + + visitors + 5 + false + EccentricGreg + null + + 7adfda8e-7c82-4ee1-88e2-6d407ff93a21 + + + visitors + 6 + false + EccentricGreg + null + + b8e2bb98-f74f-3373-a144-0107bca542b7 + + + visitors + 7 + false + greghuc + null + + 08d6ef60-f157-3a8e-a04f-6af73400697c + + + visitors + 8 + false + EnquiryStirling + null + + 28755a9a-d3ba-366a-8837-bbd63051e079 + + + visitors + 9 + false + CreativeStirling + null + + b9075e8f-4773-3d2e-a08c-64345403cc03 + + + visitors + 10 + false + johnd_7 + null + + 14801086-f435-35d3-973a-6fe8572874c9 + + + visitors + 11 + false + WookieCushion + null + + 2494bee9-581d-3809-90d8-0d199b81c0a9 + + diff --git a/server/db/reservelist.xml b/server/db/reservelist.xml new file mode 100755 index 0000000..27b9967 --- /dev/null +++ b/server/db/reservelist.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/server/db/warp.xml b/server/db/warp.xml new file mode 100755 index 0000000..77850d5 --- /dev/null +++ b/server/db/warp.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/server/db/whitelist.xml b/server/db/whitelist.xml new file mode 100755 index 0000000..05bcd14 --- /dev/null +++ b/server/db/whitelist.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/server/lang/canary/da_DK.lang b/server/lang/canary/da_DK.lang new file mode 100755 index 0000000..466a2c5 --- /dev/null +++ b/server/lang/canary/da_DK.lang @@ -0,0 +1,193 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +group created=Group created +group failed=Group creation failed +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mobspawn console=You cannot spawn Entities as console +mobspawn failed=Could not spawn mob. (Block out of range?) +mobspawn info=animals or other things +mobspawn spawned rider=Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the motto of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yes +your home=Your Home diff --git a/server/lang/canary/de_DE.lang b/server/lang/canary/de_DE.lang new file mode 100755 index 0000000..c05e8a2 --- /dev/null +++ b/server/lang/canary/de_DE.lang @@ -0,0 +1,193 @@ +EAST=Ost +NORTH=Nord +NORTHEAST=Nord-Ost +NORTHWEST=Nord-West +SOUTH=Süd +SOUTHEAST=Süd-Ost +SOUTHWEST=Süd-West +WEST=West +allow=Erlauben +ban banned={0} wurde gebannt +ban failed=Ban nicht ausgeführt. +ban info=einen Spieler bannen +compass console=Du schaust hinab von den großen Minecraft Himmeln +compass info=Zeigt die Himmelsrichtung in die du blickst +compass=Kompass: +deny=Verweigern +emote info=Zeige emotionen im chat (* spieler facepalms) +false=Falsch +getpos console=Du bist in den großen Minecraft Himmeln +getpos info=Zeigt deine aktuelle Position in der Welt +give failed=Items verschenken fehlgeschlagen +give info=Gib dir oder anderen Items +give invalid itemtype={0} is kein gültiges Item +give received=Du hast {0} bekommen +give success other={0} hat deine Items bekommen +give success=Hier +group created=Gruppe wurde erstellt +group failed=Gruppe konnte nicht erstellt werden +group remove default group=Du kannst die standard Gruppe nicht entfernen +group removed=Gruppe wurde entfernt +group unknown parent=Die Vater-Gruppe ist ungültig +group=gruppe +groupmod add=Füge eine neue Gruppe hinzu +groupmod info=Bearbeite Gruppen und Permissions +groupmod list=Zeige alle Gruppen +groupmod permission=Bearbeite Gruppen Permissions +groupmod prefix=ndere das Prefix einer Gruppe +groupmod remove=Entferne eine Gruppe +groupmod rename=Benenne eine Gruppe um +help info=Hier bekommst du Hilfe! +help not found=Keine Hilfe verfügbar +help title=Verfügbare Befehle (Seite {0} von {1} ) <> = benötigt [] = optional: +home console=Du bist bereits zuhause +home info=Teleportiere zu deinem oder ein zu einem anderen zuhause +home teleport other=Auf nach {0}'s zuhause +home teleport=Auf nach hause +ipban banned=%s's IP wurde gebannt +ipban info=einen Spieler IP bannen +kick failed=Konnte den Spieler nicht rausschmeissen +kick info=Einen Spieler rausschmeissen +kick kicked=Du hast {0} rausgeschmissen +kick message=Du wurdest von {0} rausgeschmissen +kill console=Du kannst das Terminal nicht töten. Nutzne \stop\ um den server zu stoppen. +kill info=Töte dich oder einen anderen Spieler +kill other={0} wurde getötet +kit consol=Du kannst als Terminal nicht mit Kits arbeiten +kit created group=Gruppen Item Set {0} wurde erstellt +kit created private=Privates Item Set {0} wurde erstellt +kit created=Item Set {0} wurde erstellt +kit from inventory=Erstelle sein Item Set aus deinem Inventar +kit given other=Viel spaß mit diesem Item Set von {0} +kit given=Viel spaß mit deinem Item Set +kit info=Gib dir oder anderen Item Sets oder erstelle neue. +kit invalid={0} ist kein Item Set +kit unavailable other=Dieses Item Set ist für {0} im Moment nicht verfügbar +kit unavailable=Dieses Item Set ist im Moment nicht verfügbar +lplugin info=Zeigt alle verfügbaren Plugins +lwarps info=Zeigt alle verfügbaren Warps +makevanilla info=Erstelle einen Vanilla MC Server aus den aktuellen Einstellungen +mobspawn console=Das Terminal kann kein Leben erzeugen +mobspawn failed=Konnte nichts erzeugen. (Block ausserhalb der Reichweite?) +mobspawn info=animals or other things +mobspawn spawned rider={0} wurde mit {1} als Reiter erzeugt +mobspawn spawned={0} wurde erzeugt +mode console=Das Terminal hat keinen Spiel-Modus ... +mode info=ndere deinen Spiel-Modus oder den eines anderen Spielers +mode set other={0}''s Spiel-Modus wurde zu {1} geändert +modify group removed=Gruppe entfernt +modify group set (failed)=Group has failed to set: {0} +modify group set=Gruppe wurde gesetzt +modify info=ndere eine Gruppe oder einen Spieler +modify permission added=Erlaubnis erteilt +modify permission removed=Erlaubnis entzogen +modify player removed=Spieler wurde entfernt +modify prefix removed=Prefix wurde entfernt +modify prefix set=Prefix wurde gesetzt +motd info=Zeigt das Motto des Tages +msg info=Eine private Nachricht an einen Spieler schicken. +mute info=Stelle einen Spieler stumm oder gib ihm die Stimme zurück +mute muted={0} ist jetzt stumm +mute unmuted={0} ist nicht mehr stumm +muted=Du bist stumm +no home set other={0} hat kein zuhause +no home set=Du hast noch kein zuhause. Nutze /sethome um eines zu erstellen. +no plugins=Es wurden keine Plugins geladen +no warps=Es gibt keine Warps (wow!) +no=Nein +not killed=Spieler wurde nicht getötet +off=Aus +on=An +player suicide=Du hast dich selbst getötet +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Füge einen neuen Spieler hinzu +playermod group=ndere die Gruppe eines Spielers +playermod info=Bearbeite Spieler und Permissions +playermod permission=Bearbeite die Permissiosn eines Spielers +playermod prefix=Bearbeite das Prefix eines Spielers +playermod remove=Entferne einen Spieler (aus der Datenbank) +plugin disable info=Ein Plugin deaktivieren (-p um es permanent zu deaktivieren) +plugin disabled fail=check server log +plugin disabled={0} ist nun deaktiviert +plugin enable info=Ein Plugin aktivieren (-p um es permanent zu aktivieren) +plugin enabled fail=check server log +plugin enabled={0} ist nun aktiv +plugin reload info=Ein Plugin neu laden +plugin reloaded fail=check server log +plugin reloaded={0} wurde neu geladen +private=privat +reload info=Lädt die Server- und Spielerkonfigurationen neu aus der Datenbank +reload reloading done=Konfigurationen geladen +reload reloading=Lade Konfigurationen ... +setspawn console=there is no need for a spawn point. +setspawn info=Setzte den Startpunkt in deiner Welt +setspawn success=Startpunkt wurde gesetzt +setwarp console=Du kannst keinen Warp zu den großen Minecraft Himmeln erstellen +setwarp failed=Warp konnte nicht erstellt werden +setwarp info=Erstellt einen neuen Warp Punkt +setwarp success group=Gruppen Warp {0} wurde erstellt +setwarp success private=Privater Warp {0} wurde erstellt +setwarp success=Warp {0} wurde erstellt +spawn failed console=Bitte gib eine gültige Welt und einen existierenden Spieler an +spawn failed=sorry. +spawn info=Gehe zum Startpunkt einer welt +spawn success other={0} wurde zum Startpunkt gebracht +spawn success=Du bist jetzt beim Startpunkt +stop console=Manueller server stop durch {0} +stop info=Stoppt den Server +stop player=Du kannst den Server nur im Terminal stoppen +time display=Es ist {0} (RAW ist {1}) +time info=Prüfe oder ändere die Zeit +time set day=Zeit wurde geändert. Guten Morgen! +time set night=Zeit wurde geändert. Carpe Noctem! +time set=Zeit wurde geändert +tp console=Das allmächtige Terminal sollte die Sterblichen nicht besuchen +tp info=Teleportiere dich zu einem anderen Spieler +tp success=Zu {0} teleportiert +tphere console=Das allmächtige Terminal sollte keine Sterblichen in die großen Minecraft Himmel holen! +tphere info=Bring einen anderen Spieler zu dir +tphere success={0} wurde zu dir teleportiert +true=Wahr +unknown command=Unbekannter Befehl +unknown group=Unbekannte Gruppe: {0} +unknown messagereceiver=Unbekannter Empfänger: {0} +unknown player={0} existiert nicht +usage=Nutzung: {0} +warp console=Das allmächtige Terminal hat im Reich der lebenden nichts zu erledigen +warp info=Teleportiere dich zu Warp Punkten +warp not allowed=Du darfst nicht nach {0} warpen +warp success=Zu {0} gewarpt +warp unknown={0} ist kein Warp Punkt +warps available=Verfügbare Warps +weather check=Das Wetter: {0} +weather clear=Heiter +weather console=In den großen Himmlen gibt es so etwas wie Wetter nicht! +weather info=Verändere das Wetter der Welt +weather raining=Regen +weather set clear=Das Wetter klärt sich +weather set rain=Du hast eine Regenzeit heraufbeschworen +weather set thunder=Es wird Donner geben! +weather thundering=Gewitter +whitelist info=Bearbeite die Whitelist +whitelist player added={0} wurde der Whitelist hinzugefügt +whitelist player removed=Spieler wurde von der Whitelist entfernt +who info=Zeigt eine Liste der Spieler auf dem Server +yes=Ja +your home=Dein Heim diff --git a/server/lang/canary/en_PT.lang b/server/lang/canary/en_PT.lang new file mode 100755 index 0000000..ae63f8f --- /dev/null +++ b/server/lang/canary/en_PT.lang @@ -0,0 +1,199 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Lookin' down from t' great Minecraft Skies +compass info=Displays t' cardinal direction you're lookin' at +compass=Compass: +deny=Deny +emote info=Show ye emotion in chat ye scurvy dogs! +false=False +getpos console=Your above t' great Minecraft Seas in t' sky +getpos info=Get yer current position in th' world +give failed=Givin' away ye items failed +give info=Give ye or others some of yar booty (items) +give invalid itemtype={0} ain't valid booty (item) +give received=Ye received {0} +give success other={0} received yer booty (item(s)) +give success=Thar's yer loot (item) +god disabled other=By Blackbeards Ghost, yer ({0}) be no longer a god amongst man nor woman! (Disabled). +god disabled=By Blackbeards Ghost, thar be no longer a god amongst man nor woman! . +god enabled other=yar ({0}) be a god now amongst man n woman! . +god enabled=yar be a god now amongst man n woman!. +god failed=AARRRGHH...yar god like command be failin'. +group created=yar scurvy cur o' a crew (Group) has been created. +group failed=ARRGH try again ye fail creatin' that crew (Group). +group remove default group=Ye cannot scuttle (Remove) th' default group +group removed=har har Matey! Group be scuttled (Removed) +group unknown parent=Th' specified elder group be invalid +group=group +groupmod add=Shiver me timbers! yar just created a new crew (group)! +groupmod info=Manage crew (group) 'n permissions +groupmod list=List all groups +groupmod permission=Edit crew (group) 'n permissions +groupmod prefix=Change crew (group) 'n prefix +groupmod remove=Scuttle crew (group) 'n +groupmod rename=Rename crew (group) 'n +help info=Get ye some help! +help not found=Help page nah found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=Ye be already ship (home) +home info=Teleport galleon (home) or t' someone else's galleon (home) +home teleport other=Goin' t' {0}'s ship (home) +home teleport=Goin' galleon (home) +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=Ye kicked {0} +kick message=Ye 'ave been kicked by {0} +kill console=Ye cannot scuttle th' console. Use \stop\ t' stop th' server +kill info=Kill ye or another player +kill other={0} has been scuttled +kit consol=Ye cannot work wit' kits as console +kit created group=Crew Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from yer Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy yer Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} ain't a Kit +kit unavailable other=Sink me! This kit be currently unavailable fer {0} +kit unavailable=No quarter! This kit is currently unavailable +lplugin info=Arrr! List all available plugins +lwarps info=Alas! List all available warps +makevanilla info=Blimey! Generate a Vanilla MC server from thee current Setup +mobspawn console=Shiver me timbers! Ye cannot spawn Entities as console +mobspawn failed=Well shave me belly with a rusty razor! Could not spawn mob. (Block out of range?) +mobspawn info=Yo-ho-ho! animals or other things +mobspawn spawned rider=Sail ho! Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=Arrr! Th' console has no game mode ... +mode info=Change yer owns or others game mode +mode set other={0}''s mode has been set t' {1} +modify group add=Crew has been added +modify group removed=Crew has been scuttled +modify group set (failed)=Group has failed to set: {0} +modify group set=Crew has been set +modify info=Modify a Crew or Sailor +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Sailor has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show th' message o' th' day +msg info=Send private message t' a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} Alas! has no galleon +no home set=Ye 'ave no ship set. Use /sethome t' create yer owns ship. +no plugins=No Plugins loaded +no warps=Alas! Thar be no warps (wow!) +no=No +not killed=Sink me! Sailor was not killed +off=Off +on=On +player suicide=Yarr! Ye committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Yo-ho-ho! Add a new sailor +playermod group=Sail ho! Change thee sailors crew +playermod info=Ahoy! Edit salty dog and permissions +playermod permission=Yarr! Edit permissions of a salty dogr +playermod prefix=Blimey! Edit a salty dogs prefix +playermod remove=Remove a salty dog (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload th' server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=Thar be no need fer a spawn point. +setspawn info=Set th' (real) spawn 'o ye seven seas +setspawn success=Spawn has been set +setwarp console=Ye cannot set a warp to th' great Minecraft Skies +setwarp failed=Settin' warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid seven seas 'n a valid salty dog +spawn failed=sorry. +spawn info=Be off to th' worlds spawn +spawn success other={0} has be moved to th' spawn +spawn success=Ye be now at th' spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=Ye can stop th' ship only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set th' the hour +time set day=The hour has be set. Avast, tiss a fine sunrise! +time set night=The hour has be set. Carpe Noctem! +time set=The hour has be set. +tp console=Th' almighty console may not visit th' mortals +tp info=Teleport t' another salty cur +tp success=Teleported to {0} +tphere console=Th' almighty console may nah teleport mortals into th' great Minecraft Skies! +tphere info=Teleport another scur to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=Th' almighty console has no business in th' realms 'o th' mortals +warp info=Teleport to warp points +warp not allowed=Ye're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=Th' the seven seas: {0} +weather clear=Clear +weather console=Thar be no such thin' as the seven seas in th' great Miencraft Skies! +weather info=Manipulate th' seven seas's the seven seas +weather raining=Rain +weather set clear=Clearin' th' the seven seas +weather set rain=Ye conjured a raintime +weather set thunder=Thar gunna be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yarr +your home=Ye Home diff --git a/server/lang/canary/en_US.lang b/server/lang/canary/en_US.lang new file mode 100755 index 0000000..d4c2354 --- /dev/null +++ b/server/lang/canary/en_US.lang @@ -0,0 +1,233 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +ban nocontrol=You cannot ban a player ranked higher than you +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +deop not op={0} was not an operator +deop failed=Failed to deop {0} +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies (Altitude: {0}) +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +god creative other={0} is on creative. God mode doesn't affect him. +god creative=You are on creative. God mode doesn't affect you. +god disabled other=God mode has been disabled for {0}. +god disabled=God mode has been disabled. +god enabled other=God mode has been enabled for {0}. +god enabled=God mode has been enabled. +god failed=God command failed. +group created=Group {0} has been created +group created parent=Group {0} has been created, {0} Group created as parent of {1} +group failed=Group creation failed +group failed dupe=Group creation failed, duplicate group named {0} found +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +home set console=Your home has been set to the great Minecraft Skies +home set=Your home has been set +home set other={0}''s home has been set +home set by other=Your home has been set by {0} +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kick nocontrol=You cannot kick a player ranked higher than you +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mob noflags=You didn't set any valid flags... +mob radius=Invalid Radius ({0}). Defaulting to 20. +mob worldname=You need to add the dimension qualifier to the world name... ie: default_NORMAL, or specify a proper Dimension. +mob worldexsistance=No world by the name {0} +mob worldnoload=The world is not currently loaded... +mob removecount=Destroyed {0} Mobs, {1} Passives, {2} Tamed, {3} Utility ({4} Total). +mob count={0} Mobs, {1} Passives, {2} Tamed, {3} Utility ({4} Total) in World {5}. +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group add=Group has been added +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the message of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +mute nocontrol=You cannot mute a player ranked higher than you +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +op no commandblock=Due to security concerns, Op commands are not allowed from a CommandBlock +op not allowed=You are not an operator +op failed=Failed to op {0} +op already={0} is already an operator +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations... +reservelist player added={0} added to reservelist +reservelist player removed={0} removed from reservelist +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +target not specified=You must specify a target +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +unknown world=World {0} does not exist or is not loaded +unknown dimension=Dimension type for {0} is non-existent +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You''re not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +whitelist enabled=Whitelist is now enabled +whitelist disabled=Whitelist is now disabled +whitelist reload=Whitelist reloaded +who info=Display a list of online players +world loaded=World loaded +world already loaded=World was already loaded +world deleted transfer=You have been transferred to the default world due to your current world being deleted. +world delete inprogress=Please wait while the world is removed... +world delete success=World {0} deleted +world delete fail=Unable to delete World {0} +world info notloaded=World is not currently loaded, no further information available +yes=Yes +your home=Your Home diff --git a/server/lang/canary/es_ES.lang b/server/lang/canary/es_ES.lang new file mode 100755 index 0000000..466a2c5 --- /dev/null +++ b/server/lang/canary/es_ES.lang @@ -0,0 +1,193 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +group created=Group created +group failed=Group creation failed +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mobspawn console=You cannot spawn Entities as console +mobspawn failed=Could not spawn mob. (Block out of range?) +mobspawn info=animals or other things +mobspawn spawned rider=Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the motto of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yes +your home=Your Home diff --git a/server/lang/canary/fi_FI.lang b/server/lang/canary/fi_FI.lang new file mode 100755 index 0000000..466a2c5 --- /dev/null +++ b/server/lang/canary/fi_FI.lang @@ -0,0 +1,193 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +group created=Group created +group failed=Group creation failed +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mobspawn console=You cannot spawn Entities as console +mobspawn failed=Could not spawn mob. (Block out of range?) +mobspawn info=animals or other things +mobspawn spawned rider=Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the motto of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yes +your home=Your Home diff --git a/server/lang/canary/fr_FR.lang b/server/lang/canary/fr_FR.lang new file mode 100755 index 0000000..466a2c5 --- /dev/null +++ b/server/lang/canary/fr_FR.lang @@ -0,0 +1,193 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +group created=Group created +group failed=Group creation failed +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mobspawn console=You cannot spawn Entities as console +mobspawn failed=Could not spawn mob. (Block out of range?) +mobspawn info=animals or other things +mobspawn spawned rider=Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the motto of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yes +your home=Your Home diff --git a/server/lang/canary/it_IT.lang b/server/lang/canary/it_IT.lang new file mode 100755 index 0000000..466a2c5 --- /dev/null +++ b/server/lang/canary/it_IT.lang @@ -0,0 +1,193 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +group created=Group created +group failed=Group creation failed +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mobspawn console=You cannot spawn Entities as console +mobspawn failed=Could not spawn mob. (Block out of range?) +mobspawn info=animals or other things +mobspawn spawned rider=Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the motto of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yes +your home=Your Home diff --git a/server/lang/canary/languages.txt b/server/lang/canary/languages.txt new file mode 100755 index 0000000..0061db9 --- /dev/null +++ b/server/lang/canary/languages.txt @@ -0,0 +1,51 @@ +;# This file NEEDS to be in UTF-8 format! +;# This file tells VIUtils which languages are supported +;# locale => .lang + +# English (this key needs to exist) +en_US=en_US +en_GB=en_US +en_AU=en_US +en_CA=en_US + +# Dannish +da_DK=da_DK + +# Dutch +nl_NL=nl_NL + +# Finnish +fi_FI=fi_FI + +# French +fr_FR=fr_FR + +# German - Germany +de_DE=de_DE + +# German - Switzerland +de_CH=de_CH + +# Italian +it_IT=it_IT + +# Latin +la_LA=la_LA + +# Norwegian +no_NO=no_NO + +# Polish +pl_PL=pl_PL + +# Pirate English +en_PT=en_PT + +# Russian +ru_RU=ru_RU + +# Spanish +es_ES=es_ES + +# Swedish +sv_SE=sv_SE diff --git a/server/lang/canary/nl_NL.lang b/server/lang/canary/nl_NL.lang new file mode 100755 index 0000000..0288143 --- /dev/null +++ b/server/lang/canary/nl_NL.lang @@ -0,0 +1,193 @@ +EAST=Oost +NORTH=Noord +NORTHEAST=Noordoost +NORTHWEST=Noordwest +SOUTH=Zuid +SOUTHEAST=Zuidoost +SOUTHWEST=Zuidwest +WEST=West +allow=Toestaan +ban banned={0} is verbannen +ban failed=Ban niet uitgevoerd +ban info=Verban een speler +compass console=Je kijkt neer vanuit de grote Minecrafthemel +compass info=Geeft de windrichting weer die je op kijkt +compass=Kompas: +deny=Weigeren +emote info=Toon een emotie in de chat (* speler facepalms) +false=Onwaar +getpos console=Je bent in de grote Minecraft hemel +getpos info=Verkrijg je huidige positie in de wereld +give failed=Het weggeven van voorwerpen is mislukt +give info=Geef jezelf of anderen wat voorwerpen +give invalid itemtype={0} is geen geldige voorwerp +give received=Je hebt {0} ontvangen +give success other={0} heeft jouw voorwerp(en) ontvangen +give success=Hier is je voorwerp +group created=Groep gecreëerd +group failed=Groep kon niet gecreëerd worden +group remove default group=Je kunt de standaard groep niet verwijderen +group removed=Groep verwijderd +group unknown parent=De opgegeven ouder groep is ongeldig +group=groep +groupmod add=Voeg een nieuwe groep toe +groupmod info=Creëer of verwijder groepen +groupmod list=Toon alle groepen +groupmod permission=Bewerk Groepsmachtigingen +groupmod prefix=De voorvoegsel van een groepen wijzigen +groupmod remove=Verwijder een groep +groupmod rename=Hernoem een groep +help info=Ga hulp halen! +help not found= +help title=Beschikbare commando's (pagina {0} van de {1}) <> = nodig [] = onnodig: +home console=Je hebt al een huis +home info=Teleporteer naar huis of naar dat van iemand anders +home teleport other=Naar {0}s huis +home teleport=Naar huis +ipban banned={0} is ge-IP-band +ipban info=IP-ban een speler +kick failed=Kon deze speler niet wegsturen +kick info=Een speler wegsturen +kick kicked=Je hebt {0} weggestuurd +kick message=Je bent weggestuurd door {0} +kill console=Je kunt de console niet doden. gebruik \stop\ om der server te stoppen. +kill info=Dood jezelf of een andere speler +kill other={0} is gedood +kit consol=Je kunt als console niet met uitrustingen werken +kit created group=Groeps uitrusting {0} is gecreëerd +kit created private=Privé uitrusting {0} is gecreëerd +kit created=Uitrusting {0} is gecreëerd +kit from inventory=Maak een uitrusting vanuit je inventaris +kit given other=Veel plezier met deze uitrusting van {0} +kit given=Veel plezier met je uitrusting +kit info=Geef jezelf of anderen uitrustingen of creëer nieuwe uitrustingen. +kit invalid={0} is geen uitrusting +kit unavailable other=Deze uitrusting is momenteel niet verkrijgbaar voor {0} +kit unavailable=Deze uitrusting is momenteel niet verkrijgbaar +lplugin info=Toon alle beschikbare plugins +lwarps info=Toon alle beschikbare warps +makevanilla info=Genereer een Vanilla Minecraft server van de huidige instellingen +mobspawn console=De console kan geen leven produceren +mobspawn failed=Kon niets produceren. (Blok buiten bereik?) +mobspawn info=animals or other things +mobspawn spawned rider={0} wordt geproduceerd met (1) als ruiter +mobspawn spawned={0} is geproduceerd +mode console=De console heeft geen spelmodus ... +mode info=Verander je eigen of andermans spelmodus +mode set other={0} zijn spelmodus is ingesteld op {1} +modify group removed=Groep verwijderd +modify group set (failed)=Group has failed to set: {0} +modify group set=Groep ingesteld +modify info=Wijzig een groep of speler +modify permission added=Permissie toegevoegd +modify permission removed=Permissie verwijderd +modify player removed=Speler is verwijderd +modify prefix removed=Voorvoegsel verwijderd +modify prefix set=Voorvoegzel ingesteld +motd info=Toon de motto van de dag +msg info=Verzend een privé bericht naar een speler +mute info=Breng een speler tot zwijgen of geef hem zijn stem terug +mute muted={0} is nu gedempt +mute unmuted={0} is niet meer gedempt +muted=Je bent gedempt +no home set other={0} heeft geen huis +no home set=Je hebt geen huis. Gebruik /sethome om er een te maken. +no plugins=Er zijn geen plugins geladen +no warps=Er zijn geen warps (wow!) +no=Nee +not killed=Speler is niet gedood +off=Uit +on=Aan +player suicide=Je hebt zelfmoord gepleegd +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Voeg een nieuwe speler toe +playermod group=Bewerk een spelers groep +playermod info=Spelers en machtigingen bewerken +playermod permission=bewerk de machtigingen van een speler +playermod prefix=Bewerk een spelers voorvoegsel +playermod remove=Verwijder een speler (van de database) +plugin disable info=Deactiveer een plugin (gebruik -p om het permanent te deactiveren) +plugin disabled fail=check server log +plugin disabled={0} is gedeactiveerd +plugin enable info=Activeer een plugin (gebruik -p om het permanent te activeren) +plugin enabled fail=check server log +plugin enabled={0} is geactiveerd +plugin reload info=Herlaad een plugin +plugin reloaded fail=check server log +plugin reloaded={0} is herladen +private=privé +reload info=Herlaad de server en speler configuratie van het databank +reload reloading done=Configuraties herladen +reload reloading=Herlaad de configuraties ... +setspawn console=there is no need for a spawn point. +setspawn info=Zet de (echte) spawn van je wereld +setspawn success=De spawn is gezet +setwarp console=Je kunt geen warp naar de Minecrafthemel zetten +setwarp failed=Het plaatsen van een warp punt is mislukt +setwarp info=Zet een nieuw warp punt +setwarp success group=Groeps warp {0} is gezet +setwarp success private=Privé warp {0} is gezet +setwarp success=Warp {0} is gezet +spawn failed console=Geef een geldige wereld en speler +spawn failed=sorry. +spawn info=Ga naar de werelds spawn +spawn success other={0} is verplaatst naar spawn +spawn success=Je bevindt je nu op de spawn +stop console={0} heeft de handmatige stopzetting gebruikt +stop info=Stop de server +stop player=Je kunt de server alleen via de console uitschakelen +time display=Het is {0} (RAW is {1}) +time info=Bekijk of zet de tijd +time set day=De tijd is verzet. Goedemorgen! +time set night=De tijd is verzet. Carpe Noctem! +time set=De tijd is verzet. +tp console=De almachtige console kan de stervelingen niet bezoeken +tp info=Teleporteer naar een andere speler +tp success=Geteleporteerd naar {0} +tphere console=De almachtige console mag geen stervelingen naar de Minecrafthemel teleporteren +tphere info=Teleporteer een speler naar jezelf +tphere success={0} is geteleporteerd naar jouw +true=Waar +unknown command=Onbekende Commando +unknown group=Onbekende groep: {0} +unknown messagereceiver=Onbekende ontvanger: {0} +unknown player={0} bestaat niet +usage=Gebruik: {0} +warp console=De almachtige console heeft geen zaken in het rijk der stervelingen +warp info=Teleporteer naar een warp punt +warp not allowed=Jij bent niet toegestaan om naar {0} te warpen +warp success=Naar {0} gewarpt +warp unknown={0} is geen warp +warps available=Beschikbare warps +weather check=Het weer: {0} +weather clear=Helder +weather console=Er bestaat niet zoiets als weer in de Minecrafthemel! +weather info=Verander het weer van de wereld +weather raining=Regen +weather set clear=Je hebt +weather set rain=Je hebt het laten regenen +weather set thunder=Er zal onweer zijn! +weather thundering=Onweer +whitelist info=Beheer de whitelist +whitelist player added={0} aan de whitelist toegevoegd +whitelist player removed={0} van de Whitelist verwijdert +who info=Toont een lijst met alle offline spelers +yes=Ja +your home=Je huis diff --git a/server/lang/canary/no_NO.lang b/server/lang/canary/no_NO.lang new file mode 100755 index 0000000..13724fb --- /dev/null +++ b/server/lang/canary/no_NO.lang @@ -0,0 +1,193 @@ +EAST=st +NORTH=Nord +NORTHEAST=Nord-Øst +NORTHWEST=Nord-Vest +SOUTH=Sør +SOUTHEAST=Sør-Øst +SOUTHWEST=Sør-Vest +WEST=Vest +allow=Tillat +ban banned={0} har blitt utestengt +ban failed=Utestengelse ikke utført +ban info=Utesteng en spiller +compass console=Ser ned fra den store Minecraft Himmelen +compass info=Viser deg himmelretningen du ser i +compass=Kompass: +deny=Benekt +emote info=Vis en handling i chatten (* spiller facepalmer) +false=Ikke sant +getpos console=Du er i den store Minecraft Himmelen +getpos info=Få din nåværende posisjon i verden +give failed=Kunne ikke gi itemene +give info=Gi deg selv eller noen andre items +give invalid itemtype={0} er ikke en gyldig item +give received=Du fikk {0} +give success other={0} fikk item(ene) din(e) +give success=Her +group created=Gruppe laget +group failed=Gruppe-laging feilet +group remove default group=Du kan ikke fjerne standardgruppen +group removed=Gruppe fjernet +group unknown parent=Den valgte foreldre-gruppen er ikke gyldig +group=gruppe +groupmod add=Lag en ny gruppe +groupmod info=Bearbeid grupper og tillatelser +groupmod list=List alle gruppene +groupmod permission=Rediger gruppe-tillatelser +groupmod prefix=Rediger en gruppes prefiks +groupmod remove=Fjern en gruppe +groupmod rename=Gi nytt navn til en gruppe +help info=Få hjelp! +help not found=Hjelpeside ikke funnet +help title=Tilgjengelige kommandoer (Side {0} av {1} ) <> = obligatorisk [] = valgfritt: +home console=Du er allerede hjemme +home info=Teleporter hjem eller til noen andres hus +home teleport other=Går til {0} sitt hus +home teleport=Går hjem +ipban banned={0} har blitt IP-utestengt +ipban info=Utesteng en spillers IP +kick failed=Kunne ikke kaste ut spilleren +kick info=Kast ut en spiller +kick kicked=Du kastet ut {0} +kick message=Du har blitt kastet ut av {0} +kill console=Du kan ikke drepe konsollen. Bruk \stop\ for å stoppe serveren. +kill info=Drep deg selv eller en annen spiller +kill other={0} har blitt drept +kit consol=Du kan ikke jobbe med sett fra konsollen +kit created group=Gruppe-Settet {0} har blitt laget +kit created private=Privat-Settet {0} har blitt laget +kit created=Settet {0} har blitt laget +kit from inventory=Lag et sett basert på inventaret ditt +kit given other=Ha det gøy med dette settet fra {0} +kit given=Ha det gøy med settet ditt +kit info=Gi deg selv eller noen andre sett eller lag nye sett +kit invalid={0} er ikke et sett +kit unavailable other=Dette settet er for øyeblikket ikke tilgjengelig for {0} +kit unavailable=Det settet er ikke tilgjengelig for øyeblikket +lplugin info=Vis alle tilgjengelige pluginer +lwarps info=Vis alle tilgjengelige warps +makevanilla info=Generer en Vanilla Minecraft-server fra det nåværende oppsettet +mobspawn console=Du kan ikke skape en skapning fra konsollen +mobspawn failed=Kunne ikke skape skapningen. (Er blocken for langt vekke?) +mobspawn info=animals or other things +mobspawn spawned rider=Skapning {0} skapt med {1} som rider +mobspawn spawned=Skapte {0} +mode console=Konsollen har ikke noe spill-modus ... +mode info=Endre ditt eller noen andre sitt spill-modus +mode set other={0} sitt spill-modus har blitt satt til {1} +modify group removed=Gruppen er fjernet +modify group set (failed)=Group has failed to set: {0} +modify group set=Gruppen har blitt sat +modify info=Rediger en gruppe eller en spiller +modify permission added=Tillatelse laget +modify permission removed=Tillatelse fjernet +modify player removed=Spiller har blitt fjernet +modify prefix removed=Prefiks fjernet +modify prefix set=Prefiks satt +motd info=Vis dagens motto +msg info=Send en privatmelding til en spiller +mute info=Gjør en spiller stum eller ikke stum +mute muted={0} er nå stum +mute unmuted={0} er nå ikke stum +muted=Du er stum +no home set other={0} har ikke et hus +no home set=Du har ikke satt ett hjem. Bruk /sethome for å sette et hjem. +no plugins=Ingen pluginer aktivert +no warps=Det finnes ingen warps (wow!) +no=Nei +not killed=Spiller ble ikke drept +off=Av +on=På +player suicide=Du tok selvmord +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Legg til en ny spiller +playermod group=Bytt spillerens gruppe +playermod info=Rediger spillere og tillatelser +playermod permission=Rediger en spillers tillatelser +playermod prefix=Rediger en spillers prefiks +playermod remove=Fjern en spiller (fra databasen) +plugin disable info=Deaktiver en plugin (bruk -p for å deaktivere den permanent) +plugin disabled fail=check server log +plugin disabled={0} er nå deaktivert +plugin enable info=Aktiver en plugin (bruk -p for å aktivere den permanent) +plugin enabled fail=check server log +plugin enabled={0} er nå aktivert +plugin reload info=Reaktiver en plugin +plugin reloaded fail=check server log +plugin reloaded={0} er nå reaktivert +private=privat +reload info=Reaktiver serveren og spiller-konfigurasjoner fra database +reload reloading done=Konfigurasjoner reaktivert +reload reloading=Reaktiverer konfigurasjoner ... +setspawn console=there is no need for a spawn point. +setspawn info=Sett den (ekte) start-plassen i verdenen din +setspawn success=Start-plass satt +setwarp console=Du kan ikke sette en warp i Den Store Minecraft-himmelen +setwarp failed=Warp-plassen kunne ikke bli satt +setwarp info=Setter en ny warp-plass +setwarp success group=Gruppe-warp {0} satt +setwarp success private=Privat-warp {0} satt +setwarp success=Warp {0} satt +spawn failed console=Vennligst oppgi en gyldig verden og en gyldig spiller +spawn failed=sorry. +spawn info=Gå til verdenens start-plass +spawn success other={0} har blitt flyttet til start-plassen +spawn success=Du er nå på start-plassen +stop console={0} har utført en manuell avslutning +stop info=Stopp serveren +stop player=Du kan bare stoppe serveren fra terminalen +time display=Den er {0} (RAW er {1}) +time info=Sjekk eller sett tiden +time set day=Tiden har blitt satt. God morgen! +time set night=Tiden har blitt satt. God natt! +time set=Tiden har blitt satt. +tp console=Den almektige terminalen kan ikke besøke de dødelige +tp info=Teleporter til en annen spiller +tp success=Teleporterte til {0} +tphere console=Den almektige terminalen kan ikke teleportere dødelige til den Store Minecraft-himmelen +tphere info=Teleporter en annen spiller til deg +tphere success={0} har blitt teleportert til deg +true=Sant +unknown command=Ukjent kommando +unknown group=Ukjent gruppe: {0} +unknown messagereceiver=Ukjent mottaker: {0} +unknown player={0} eksisterer ikke +usage=Bruk: {0} +warp console=Den almektige terminalen har ikke noe å gjøre i de dødeliges verden +warp info=Teleporter til et warp-punkt +warp not allowed=Du har ikke lov til å warpe til {0} +warp success=Warpet til {0} +warp unknown={0} er ikke et warp-punkt +warps available=Tilgjengelige warps +weather check=Været: {0} +weather clear=Blå himmel +weather console=Det finnes ikke vær i den Store Minecraft-himmelen! +weather info=Manipuler verdenens vær +weather raining=Regn +weather set clear=Fjerner torden/regn +weather set rain=Du har satt været til regn +weather set thunder=Det skal bli tordenvræl! +weather thundering=Torden +whitelist info=Administrer hvitelisten +whitelist player added={0} lagt til i hvitelisten +whitelist player removed={0} fjernet fra hvitelisten +who info=Vis en liste av påloggede spillere +yes=Ja +your home=Ditt hjem diff --git a/server/lang/canary/pl_PL.lang b/server/lang/canary/pl_PL.lang new file mode 100755 index 0000000..466a2c5 --- /dev/null +++ b/server/lang/canary/pl_PL.lang @@ -0,0 +1,193 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +group created=Group created +group failed=Group creation failed +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mobspawn console=You cannot spawn Entities as console +mobspawn failed=Could not spawn mob. (Block out of range?) +mobspawn info=animals or other things +mobspawn spawned rider=Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the motto of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yes +your home=Your Home diff --git a/server/lang/canary/ru_RU.lang b/server/lang/canary/ru_RU.lang new file mode 100755 index 0000000..466a2c5 --- /dev/null +++ b/server/lang/canary/ru_RU.lang @@ -0,0 +1,193 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +group created=Group created +group failed=Group creation failed +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mobspawn console=You cannot spawn Entities as console +mobspawn failed=Could not spawn mob. (Block out of range?) +mobspawn info=animals or other things +mobspawn spawned rider=Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the motto of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yes +your home=Your Home diff --git a/server/lang/canary/sv_SE.lang b/server/lang/canary/sv_SE.lang new file mode 100755 index 0000000..466a2c5 --- /dev/null +++ b/server/lang/canary/sv_SE.lang @@ -0,0 +1,193 @@ +EAST=East +NORTH=North +NORTHEAST=North East +NORTHWEST=North West +SOUTH=South +SOUTHEAST=South East +SOUTHWEST=South West +WEST=West +allow=Allow +ban banned={0} has been banned +ban failed=Ban not issued +ban info=Ban a player +compass console=Looking down from the great Minecraft Skies +compass info=Displays the cardinal direction you're looking at +compass=Compass: +deny=Deny +emote info=Show an emotion in chat (* player facepalms) +false=False +getpos console=You are in the great Minecraft Skies +getpos info=Get your current position in the world +give failed=Giving away items failed +give info=Give you or others some items +give invalid itemtype={0} is not a valid item +give received=You received {0} +give success other={0} received your item(s) +give success=There's your item +group created=Group created +group failed=Group creation failed +group remove default group=You cannot remove the default group +group removed=Group removed +group unknown parent=The specified parent group is invalid +group=group +groupmod add=Add a new group +groupmod info=Manage groups and permissions +groupmod list=List all groups +groupmod permission=Edit group permissions +groupmod prefix=Change a groups prefix +groupmod remove=Remove a group +groupmod rename=Rename a group +help info=Get some help! +help not found=Help page not found +help title=Available commands (Page {0} of {1} ) <> = required [] = optional: +home console=You are already home +home info=Teleport home or to someone else's home +home teleport other=Going to {0}'s home +home teleport=Going home +ipban banned={0} has been IP banned +ipban info=IP Ban a player +kick failed=Couldn't kick player +kick info=Kick a player +kick kicked=You kicked {0} +kick message=You have been kicked by {0} +kill console=You cannot kill the console. Use \stop\ to stop the server +kill info=Kill you or another player +kill other={0} has been killed +kit consol=You cannot work with kits as console +kit created group=Group Kit {0} has been created +kit created private=Private Kit {0} has been created +kit created=Kit {0} has been created +kit from inventory=Create a Kit from your Inventory +kit given other=Enjoy this Kit from {0} +kit given=Enjoy your Kit +kit info=Give yourself or others kits or create new kits +kit invalid={0} is not a Kit +kit unavailable other=This kit is currently unavailable for {0} +kit unavailable=This kit is currently unavailable +lplugin info=List all available plugins +lwarps info=List all available warps +makevanilla info=Generate a Vanilla MC server from the current Setup +mobspawn console=You cannot spawn Entities as console +mobspawn failed=Could not spawn mob. (Block out of range?) +mobspawn info=animals or other things +mobspawn spawned rider=Mob {0} spawned with {1} as rider +mobspawn spawned=Spawned {0} +mode console=The console has no game mode ... +mode info=Change your own or others game mode +mode set other={0}''s mode has been set to {1} +modify group removed=Group removed +modify group set (failed)=Group has failed to set: {0} +modify group set=Group has been set +modify info=Modify a group or player +modify permission added=Permission added +modify permission removed=Permission removed +modify player removed=Player has been removed +modify prefix removed=Prefix removed +modify prefix set=Prefix set +motd info=Show the motto of the day +msg info=Send private message to a player +mute info=Mute or unmute a player +mute muted={0} is now muted +mute unmuted={0} is now unmuted +muted=You are muted +no home set other={0} has no home +no home set=You have no home set. Use /sethome to create your own home. +no plugins=No Plugins loaded +no warps=There are no warps (wow!) +no=No +not killed=Player was not killed +off=Off +on=On +player suicide=You committed suicide +playerinfo firstjoin=First Joined: {0} +playerinfo lastjoined=Last Joined: {0} +playerinfo timeplayed=Time Played: {0} +playerinfo muted=Muted: {0} +playerinfo prefix=Prefix: {0} +playerinfo ip=IP: {0} +playerinfo primarygroup=Primary Group: {0} +playerinfo subgroups=Other Groups: {0} +playerinfo health=Health: {0} +playerinfo gamemode=GameMode: {0} +playerinfo foodlevel=Food Level: {0} +playerinfo foodexhaustion=Food Exhaustion: {0} +playerinfo xplevel=XP Level: {0} +playerinfo xptotal=XP Total: {0} +playerinfo position=Position: {0} +playerinfo world=World: {0} +playerinfo homeset=Home: {0} +playerinfo homeunset=Home: Not set +playermod add=Add a new player +playermod group=Change the players group +playermod info=Edit players and permissions +playermod permission=Edit permissions of a player +playermod prefix=Edit a players prefix +playermod remove=Remove a player (from database) +plugin disable info=Disable plugin (use -p to permanently disable it) +plugin disabled fail=check server log +plugin disabled={0} has been disabled +plugin enable info=Enable a plugin (use -p to permanently enable it) +plugin enabled fail=check server log +plugin enabled={0} has been enabled +plugin reload info=Reload a plugin +plugin reloaded fail=check server log +plugin reloaded={0} has been reloaded +private=private +reload info=Reload the server and player configurations from database +reload reloading done=Configurations reloaded +reload reloading=Reloading configurations ... +setspawn console=there is no need for a spawn point. +setspawn info=Set the (real) spawn of your world +setspawn success=Spawn has been set +setwarp console=You cannot set a warp to the great Minecraft Skies +setwarp failed=Setting warp point failed +setwarp info=Sets a new warp point +setwarp success group=Group warp {0} has been set +setwarp success private=Private warp {0} has been set +setwarp success=Warp {0} has been set +spawn failed console=Please specify a valid world and a valid player +spawn failed=sorry. +spawn info=Go to the worlds spawn +spawn success other={0} has been moved to the spawn +spawn success=You are now at the spawn +stop console={0} issued a manual shutdown +stop info=Stops the server +stop player=You can stop the server only as Console +time display=It is {0} (RAW is {1}) +time info=Check or set the time +time set day=Time has been set. Good morning! +time set night=Time has been set. Carpe Noctem! +time set=Time has been set. +tp console=The almighty console may not visit the mortals +tp info=Teleport to another player +tp success=Teleported to {0} +tphere console=The almighty console may not teleport mortals into the great Minecraft Skies! +tphere info=Teleport another player to you +tphere success={0} has been teleported to you +true=True +unknown command=Unknown command +unknown group=Unknown group: {0} +unknown messagereceiver=Unknown Message Receiver: {0} +unknown player={0} does not exist +usage=Usage: {0} +warp console=The almighty console has no business in the realms of the mortals +warp info=Teleport to warp points +warp not allowed=You're not allowed to warp to {0} +warp success=Warped to {0} +warp unknown={0} is not a Warp +warps available=Available Warps +weather check=The weather: {0} +weather clear=Clear +weather console=There is no such thing as weather in the great Miencraft Skies! +weather info=Manipulate the world's weather +weather raining=Rain +weather set clear=Clearing the weather +weather set rain=You conjured a raintime +weather set thunder=There will be thunder! +weather thundering=Thunder +whitelist info=Manage the whitelist +whitelist player added={0} added to whitelist +whitelist player removed={0} removed from whitelist +who info=Display a list of online players +yes=Yes +your home=Your Home diff --git a/server/logs/2015-09-12-1.log.gz b/server/logs/2015-09-12-1.log.gz new file mode 100644 index 0000000..ac10f85 Binary files /dev/null and b/server/logs/2015-09-12-1.log.gz differ diff --git a/server/logs/2015-09-12-2.log.gz b/server/logs/2015-09-12-2.log.gz new file mode 100644 index 0000000..367a454 Binary files /dev/null and b/server/logs/2015-09-12-2.log.gz differ diff --git a/server/logs/2015-09-12-3.log.gz b/server/logs/2015-09-12-3.log.gz new file mode 100644 index 0000000..3c72999 Binary files /dev/null and b/server/logs/2015-09-12-3.log.gz differ diff --git a/server/logs/2015-09-12-4.log.gz b/server/logs/2015-09-12-4.log.gz new file mode 100644 index 0000000..ec20acf Binary files /dev/null and b/server/logs/2015-09-12-4.log.gz differ diff --git a/server/logs/2015-09-12-5.log.gz b/server/logs/2015-09-12-5.log.gz new file mode 100644 index 0000000..da5c69f Binary files /dev/null and b/server/logs/2015-09-12-5.log.gz differ diff --git a/server/logs/2015-09-12-6.log.gz b/server/logs/2015-09-12-6.log.gz new file mode 100644 index 0000000..a922940 Binary files /dev/null and b/server/logs/2015-09-12-6.log.gz differ diff --git a/server/logs/2015-09-12-7.log.gz b/server/logs/2015-09-12-7.log.gz new file mode 100644 index 0000000..94b8924 Binary files /dev/null and b/server/logs/2015-09-12-7.log.gz differ diff --git a/server/logs/latest.log b/server/logs/latest.log new file mode 100644 index 0000000..b048954 --- /dev/null +++ b/server/logs/latest.log @@ -0,0 +1,32 @@ +[15:43:40] [CanaryMod] [INFO]: Starting: CanaryMod 1.8.0-1.2.1-SNAPSHOT +[15:43:40] [CanaryMod] [INFO]: Canary Path: /vagrant/lib/CanaryMod-1.8.0-1.2.1-SNAPSHOT-shaded.jar & Working From: /vagrant/server +[15:43:40] [CanaryMod] [INFO]: Registered xml Database +[15:43:40] [CanaryMod] [INFO]: Found 1 plugins; total: 1 +[15:43:42] [net.minecraft.server.dedicated.DedicatedServer] [INFO]: Starting minecraft server version 1.8 +[15:43:42] [net.minecraft.server.dedicated.DedicatedServer] [INFO]: Loading properties +[15:43:42] [net.minecraft.server.dedicated.DedicatedServer] [INFO]: Generating keypair +[15:43:42] [net.minecraft.server.dedicated.DedicatedServer] [INFO]: Starting Minecraft server on *:25565 +[15:43:42] [net.minecraft.server.dedicated.DedicatedServer] [WARN]: **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE! +[15:43:42] [net.minecraft.server.dedicated.DedicatedServer] [WARN]: The server will make no attempt to authenticate usernames. Beware. +[15:43:42] [net.minecraft.server.dedicated.DedicatedServer] [WARN]: While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose. +[15:43:42] [net.minecraft.server.dedicated.DedicatedServer] [WARN]: To change this, set "online-mode" to "true" in the server.properties file. +[15:43:42] [CanaryMod] [INFO]: Enabling early Plugins... +[15:43:43] [CanaryMod] [INFO]: Enabling late Plugins... +[15:43:43] [CanaryMod] [INFO]: Enabling plugin ScriptCraft +[15:43:44] [ScriptCraft] [WARN]: alias plugin is not yet supported in CanaryMod +[15:43:45] [ScriptCraft] [INFO]: Blackboard turned on for all players on server 192.168.0.9 +[15:43:45] [ScriptCraft] [WARN]: commando-test not yet supported in CanaryMod +[15:43:45] [ScriptCraft] [WARN]: commando plugin is not yet supported in CanaryMod +[15:43:46] [ScriptCraft] [WARN]: cow-clicker minigame is not yet supported in CanaryMod and Craftbukkit +[15:43:46] [net.minecraft.server.MinecraftServer] [INFO]: Preparing start region for level Roshar_NORMAL (0) +[15:43:47] [net.minecraft.server.MinecraftServer] [INFO]: Preparing spawn area: 4% +[15:43:48] [net.minecraft.server.dedicated.DedicatedServer] [INFO]: Done (5.473s)! For help, type "help" or "?" +[15:43:48] [ScriptCraft] [INFO]: js-patch setTimeout() test complete +[15:43:55] [net.minecraft.server.management.ServerConfigurationManager] [INFO]: greghuc[/192.168.0.3:56137] logged in with entity id 389 at (360.18921518243815, 6.0, -336.4007386695203) +[15:43:56] [ScriptCraft] [INFO]: Enabling scripting for player greghuc +[15:43:56] [net.minecraft.server.MinecraftServer] [INFO]: greghuc joined the game +[15:43:59] [net.minecraft.server.MinecraftServer] [WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 2669ms behind, skipping 53 tick(s) +[15:45:25] [net.minecraft.server.MinecraftServer] [INFO]: Preparing start region for level Roshar_END (1) +[15:45:26] [net.minecraft.server.MinecraftServer] [INFO]: Preparing spawn area: 52% +[15:48:38] [net.minecraft.network.NetHandlerPlayServer] [INFO]: greghuc lost connection: Disconnected +[15:48:38] [net.minecraft.server.MinecraftServer] [INFO]: greghuc left the game diff --git a/server/plugins/scriptcraft-blackboard.jar b/server/plugins/scriptcraft-blackboard.jar new file mode 100755 index 0000000..24fa474 Binary files /dev/null and b/server/plugins/scriptcraft-blackboard.jar differ diff --git a/server/plugins/scriptcraft.jar b/server/plugins/scriptcraft.jar deleted file mode 100644 index 8acd06e..0000000 Binary files a/server/plugins/scriptcraft.jar and /dev/null differ diff --git a/server/run-server.sh b/server/run-server.sh index 6551713..097c3f3 100755 --- a/server/run-server.sh +++ b/server/run-server.sh @@ -1,4 +1,6 @@ #!/bin/bash -# Start minecraft server +SERVER_DIR=`readlink -f "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"` + +cd ${SERVER_DIR} java -Xmx1024M -jar ../lib/CanaryMod-1.8.0-1.2.1-SNAPSHOT-shaded.jar -o true \ No newline at end of file diff --git a/server/scriptcraft/blackboard/stirling/buildings.js b/server/scriptcraft/blackboard/stirling/buildings.js new file mode 100755 index 0000000..22feff8 --- /dev/null +++ b/server/scriptcraft/blackboard/stirling/buildings.js @@ -0,0 +1,478 @@ +/* + Creative Stirling / CoderDojo plan to run a demo at OpenDoors 2015. + The idea is that people will be able to 'build an old Stirling street' - by coding it in Minecraft. + By 'coding', people will be able to call a set of pre-existing Javascript functions, which create + buildings, streets, signs, etc. Some variation in construction will be possible, e.g. the number of + building storeys can be specified. + + This file contains the project Javascript code. + Each Javascript function is callable from inside the Minecraft client (if setup with Scriptcraft). + So to call the house function, you run from the Minecraft prompt 'js stirling.house()' + All function calls need to prefixed with 'stirling.' + + We'd like to add more construction functions (more house types?). + Read the code below to get a feel for how we're creating things in the Minecraft. + We're basically using an awesome project called Scriptcraft, which lets people code in Minecraft using + Javascript: https://github.com/walterhiggins/ScriptCraft + + Scriptcraft has lots of docs to help you get started: https://github.com/walterhiggins/ScriptCraft#further-reading + But to shortcut a lot of reading, we're using its Drone functionality: + https://github.com/walterhiggins/ScriptCraft/blob/master/docs/API-Reference.md#drone-plugin + + Final tip. Use the list of Minecraft block types (and ids) at: http://www.minecraftinfo.com/idlist.htm + We need to specify block types when building (e.g. 'stone' house) + */ + +exports.house = function(widthInWindows, heightInFloors, material, dormers) { + widthInWindows = capNumber(getNumber(widthInWindows, null), 9); + heightInFloors = capNumber(getNumber(heightInFloors, null), 5); + if ((widthInWindows === null) || (heightInFloors === null)) { + echo(self, 'Please give the width and height of house (in windows), as numbers'); + return; + } + + var blockIds = getValueForString(material, { + 'stone': { + ground: 1, + upper: 1 + }, + 'sandstone': { + ground: 24, + upper: 24 + }, + 'brick': { + ground: 98, + upper: 98 + } + }); + var doorType = 'single'; + var isGable = false; + var hasDormers = getValueForString(dormers, { 'dormers': true, 'nodormers': false }, 'nodormers'); + innerHouse(widthInWindows, heightInFloors, blockIds, doorType, isGable, hasDormers); +}; + +exports.housewithshop = function(widthInWindows, heightInFloors, material, dormers) { + widthInWindows = capNumber(getNumber(widthInWindows, null), 9); + heightInFloors = capNumber(getNumber(heightInFloors, null), 5); + if ((widthInWindows === null) || (heightInFloors === null)) { + echo(self, 'Please give the width and height of house (in windows), as numbers'); + return; + } + + var shopColors = [ '159:1', '159:2', '159:3', + '159:4', '159:5', '159:6', + '159:7', '159:8', '159:9', + '159:10', '159:11', '159:12']; + var blockIds = getValueForString(material, { + 'stone': { + ground: randomValueFromArray(shopColors), + upper: 1 + }, + 'sandstone': { + ground: randomValueFromArray(shopColors), + upper: 24 + }, + 'brick': { + ground: randomValueFromArray(shopColors), + upper: 98 + } + }); + var doorType = 'double'; + var isGable = false; + var hasDormers = getValueForString(dormers, { 'dormers': true, 'nodormers': false }, 'nodormers'); + innerHouse(widthInWindows, heightInFloors, blockIds, doorType, isGable, hasDormers); +}; + +exports.gablehouse = function(widthInWindows, heightInFloors, material, dormers) { + widthInWindows = capNumber(getNumber(widthInWindows, null), 3); + heightInFloors = capNumber(getNumber(heightInFloors, null), 5); + if ((widthInWindows === null) || (heightInFloors === null)) { + echo(self, 'Please give the width and height of house (in windows), as numbers'); + return; + } + + var blockIds = getValueForString(material, { + 'stone': { + ground: 1, + upper: 1 + }, + 'sandstone': { + ground: 24, + upper: 24 + }, + 'brick': { + ground: 98, + upper: 98 + } + }); + var doorType = 'single'; + var isGable = true; + var hasDormers = getValueForString(dormers, { 'dormers': true, 'nodormers': false }, 'nodormers'); + innerHouse(widthInWindows, heightInFloors, blockIds, doorType, isGable, hasDormers); +}; + +exports.gablehousewithshop = function(widthInWindows, heightInFloors, material, dormers) { + widthInWindows = capNumber(getNumber(widthInWindows, null), 3); + heightInFloors = capNumber(getNumber(heightInFloors, null), 5); + if ((widthInWindows === null) || (heightInFloors === null)) { + echo(self, 'Please give the width and height of house (in windows), as numbers'); + return; + } + + var shopColors = [ '159:1', '159:2', '159:3', + '159:4', '159:5', '159:6', + '159:7', '159:8', '159:9', + '159:10', '159:11', '159:12']; + var blockIds = getValueForString(material, { + 'stone': { + ground: randomValueFromArray(shopColors), + upper: 1 + }, + 'sandstone': { + ground: randomValueFromArray(shopColors), + upper: 24 + }, + 'brick': { + ground: randomValueFromArray(shopColors), + upper: 98 + } + }); + var doorType = 'double'; + var isGable = true; + var hasDormers = getValueForString(dormers, { 'dormers': true, 'nodormers': false }, 'nodormers'); + innerHouse(widthInWindows, heightInFloors, blockIds, doorType, isGable, hasDormers); +}; + +var innerHouse = function(widthInWindows, heightInFloors, blockIds, doorType, isGable, hasDormers) { + var windowSectionWidth = 4; + var depth = 10; + //http://www.minecraftinfo.com/cobblestonestairs.htm + var roofBlockId = 67; + var dormerHeight = 2; + + //Start drone up one block, as assume cursor is pointing at ground tile + var drone = newDrone().up(); + + //Floors + var i; + for (i = 1; i <= heightInFloors; i++) { + var groundFloor = i == 1; + var doorType = groundFloor ? doorType : null; + var blockId = groundFloor ? blockIds.ground : blockIds.upper; + drone = storey(drone, blockId, widthInWindows, windowSectionWidth, depth, doorType); + } + + var roofStart = 'roofStart'; + + //Roof + var roofWidth = widthInWindows * windowSectionWidth; + if (isGable) { + drone.right(roofWidth - 1).turn(3); + roofWidth = depth; + depth = widthInWindows * windowSectionWidth; + } else { + roofWidth = widthInWindows * windowSectionWidth; + } + + drone.chkpt(roofStart); + drone.prism0(roofBlockId, roofWidth, depth); + + //Chimneys + //http://www.minecraftinfo.com/stonebricks.htm + var chimneyBlockId = 98; + var chimneyPos = depth * 0.3; + var chimneyHeight = depth * 0.6; + var chimneyWidth = Math.ceil((depth / 2) - 1); + var chimneyDepth = 1; + drone.move(roofStart).fwd(chimneyPos) + .box(chimneyBlockId, chimneyDepth, chimneyHeight, chimneyWidth) + .right(roofWidth - chimneyDepth) + .box(chimneyBlockId, chimneyDepth, chimneyHeight, chimneyWidth); + + //Dormers + //TODO: Not confused this works properly for gable-end buildings, but seems to! (with current constants) + if (hasDormers) { + var dormerOffset = ((2 * windowSectionWidth) - windowSectionWidth) / 2; + + var doubleSections = Math.floor(widthInWindows / 2); + var doubleSectionStart; + for (i = 1; i <= doubleSections; i++) { + drone.move(roofStart); + doubleSectionStart = (i - 1) * (windowSectionWidth * 2); + drone.right(doubleSectionStart); + drone.right(dormerOffset); + dormer(drone, blockId, roofBlockId, windowSectionWidth, dormerHeight, depth); + } + } +}; + +var dormer = function(drone, bodyBlockId, roofBlockId, width, height, depth) { + var numberOfTurns = 3; + var windowBlockId = 102; + var windowDepth = 1; + + var windowOffset = 1; + var windowWidth = width - (2 * windowOffset); + var windowHeight = height; + + var dormerStart = 'dormerStart'; + drone.chkpt(dormerStart); + drone.box0(bodyBlockId, width, height, depth); + drone.up(height).right(width - 1).turn(numberOfTurns).prism(roofBlockId, depth, width); + drone.move(dormerStart).right(windowOffset).box( windowBlockId, windowWidth, windowHeight, windowDepth ); + drone.move(dormerStart).fwd(depth - windowDepth).right(windowOffset).box( windowBlockId, windowWidth, windowHeight, windowDepth ); +}; + +var storey = function(drone, blockId, sectionsAcross, sectionWidth, depth, doorType) { + var frontStart = 'frontStart'; + var backStart = 'backStart'; + var sectionHeight = 4; + + var middleSection = Math.ceil(sectionsAcross/2); + + var sectionWindowWidth = sectionWidth - 2; + var sectionWindowHeight = sectionHeight - 2; + var glassBlockId = 102; //http://www.minecraftinfo.com/glasspane.htm + + + drone.box0(blockId, sectionsAcross * sectionWidth, sectionHeight, depth); + + drone.chkpt(frontStart); + drone.fwd(depth - 1).right((sectionsAcross * sectionWidth) - 1).turn(2); + drone.chkpt(backStart); + var checkpoints = [frontStart, backStart]; + + var i, j, start, drawDoor; + for (i = 0; i < checkpoints.length; i++) { + start = checkpoints[i]; + drone.move(start); + + for (j = 1; j <= sectionsAcross; j++) { + drawDoor = (doorType !== null) && (j == middleSection); + + if (drawDoor) { + var doorFunc = getValueForString(doorType, { 'single': 'door', 'double': 'door2' }, 'single'); + drone.move(start).right((j - 1) * sectionWidth).right(1)[doorFunc](); + } else { + drone.move(start) + .right((j - 1) * sectionWidth) + .up(1) + .right(1) + .box(glassBlockId, sectionWindowWidth, sectionWindowHeight, 1 ); + } + } + } + + return drone.move(frontStart).up(sectionHeight); +}; + +//length: height > 0 +//if height is left undefined, will use default value +exports.lamppost = function(height) { + var lamppostBlockId = 42; //http://www.minecraftinfo.com/blockofiron.htm + var lightBlockId = 89; //http://www.minecraftinfo.com/beacon.htm + + height = capNumber(getNumber(height, null), 10); + if (height === null) { + echo(self, 'Please give the height of lamppost, as number'); + return; + } + + var drone = newDrone(); + + //Use height + 1, as assume cursor is pointing at ground tile + drone.box(lamppostBlockId, 1, height + 1, 1) + .up(height) + .box(lightBlockId, 1, 1, 1); +}; + +//width: number > 0 +//length: number > 0 +//if width or length are left undefined, will use default values +exports.garden = function(width, length) { + width = capNumber(getNumber(width, null), 20); + length = capNumber(getNumber(length, null), 20); + if ((width === null) || (length === null)) { + echo(self, 'Please give the width and length of garden, as numbers'); + return; + } + + var drone = newDrone(); + drone.garden(width,length); +}; + +//type: 'birch', 'oak', 'spruce' +//if type is left undefined, will use default value +exports.tree = function(type) { + var treeTypes = ['birch', 'oak', 'spruce']; + type = getStringOf(type, treeTypes, null); + if (type === null) { + echo(self, 'Please give the type of tree: ' + treeTypes.map(function(value) { return '"' + value + '"'; }).join(', ')); + return; + } + + var drone = newDrone(); + drone[type](); +}; + +//mesage: string +//if message is undefined, will use default value +exports.sign = function(message) { + message = getString(message, null); + if (message === null) { + echo(self, 'Please give the message for the sign, like: ' + '"' + 'I am a message' + '"'); + return; + } + + var drone = newDrone(); + //Move up, as assume cursor is pointing at ground tile. And sign should be on surface + drone.up().signpost(splitStringIntoLines(message, 15)); +}; + +//mesage: string +//if message is undefined, will use default value +exports.wallsign = function(message) { + message = getString(message, null); + if (message === null) { + echo(self, 'Please give the message for the wall-sign, like: ' + '"' + 'I am a message' + '"'); + return; + } + + var drone = newDrone(); + drone.wallsign(splitStringIntoLines(message, 15)); +}; + + +//Not for public consumption + +//type 'cobbles', 'dirt', or 'stone' +//width: number > 0 +//length: number > 0 +//if blockType, width or length are left undefined, will use default values +exports.road = function(type, width, length) { + //http://www.minecraftinfo.com/stone.htm + //http://www.minecraftinfo.com/cobblestone.htm + //http://www.minecraftinfo.com/dirt.htm + var blockId = getValueForString(type, { 'cobbles': 4, 'dirt': 3, 'stone': 1 }, 'cobbles'); + width = getNumber(width, 9); + length = getNumber(length, 20); + + var drone = newDrone(); + drone.box(blockId, width, 1, length); +}; + +//type 'dirt', or 'stone' +//width: number > 0 +//length: number > 0 +//if blockType, width or length are left undefined, will use default values +exports.pavement = function(type, width, length) { + //http://www.minecraftinfo.com/stonebrickslab.htm + //http://www.minecraftinfo.com/dirt.htm + + var blockId = getValueForString(type, { 'dirt': 3, 'stone': '44:5' }, 'stone'); + width = getNumber(width, 3); + length = getNumber(length, 20); + + var drone = newDrone(); + drone.box(blockId, width, 2, length); +}; + +exports.air = function(width, height, depth) { + var drone = newDrone().up(); + var airBlockId = 0; //http://www.minecraftinfo.com/air.htm + + drone.box(airBlockId, width, height, depth); +}; + +exports.grass = function(width, height, depth) { + var drone = newDrone().up(); + var grassBlockId = 2; + + drone.box(grassBlockId, width, height, depth); +}; + +//Helper functions below this point + +var newDrone = function() { + return new Drone(self); +} + +var getValueForString = function (input, valueForString) { + var value = input; + + if ((value == undefined) || + (typeof value != 'string')) { + + value = randomKeyFromObject(valueForString); + } + + return valueForString[value]; +} + +var getStringOf = function(input, acceptableValues, fallbackValue) { + var value = input; + + if ((value == undefined) || + (typeof value != 'string') || + (acceptableValues.indexOf(value) < 0)) { + + value = fallbackValue; + } + + return value; +}; + +var getString = function(input, fallbackValue) { + var value = input; + + if ((value == undefined) || + (typeof value != 'string')) { + value = fallbackValue; + } + + return value; +}; + +var getNumber = function(input, fallbackValue) { + var value = input; + + if ((value === undefined) || + (typeof value != 'number') || + (value <= 0)) { + value = fallbackValue; + } + + return value; +}; + +var capNumber = function(input, maxValue) { + if (typeof input != 'number') { return input; } + return input <= maxValue ? input : maxValue; +}; + +var splitStringIntoLines = function(value, maxLineLength) { + return value.split(/\s+/).reduce(function (lines, word) { + var lastLine = lines[lines.length - 1]; + + if ((lastLine == undefined) || (lastLine.length + 1 + word.length > maxLineLength)) { + lines.push(new String(word)); + } else { + lines[lines.length - 1] = lastLine + ' ' + word; + } + + return lines; + }, []); +}; + +var randomKeyFromObject = function(obj) { + var keys = Object.keys(obj); + return keys[randomIntFromInterval(0, keys.length - 1)]; +}; + +var randomValueFromArray = function(arr) { + return arr[randomIntFromInterval(0, arr.length - 1)]; +}; + +var randomIntFromInterval = function (min,max) { + return Math.floor(Math.random()*(max-min+1)+min); +}; \ No newline at end of file diff --git a/server/scriptcraft/data/alias-store.json b/server/scriptcraft/data/alias-store.json new file mode 100755 index 0000000..7f2b037 --- /dev/null +++ b/server/scriptcraft/data/alias-store.json @@ -0,0 +1,4 @@ +{ + "players": {}, + "global": {} +} diff --git a/server/scriptcraft/data/arrows-store.json b/server/scriptcraft/data/arrows-store.json new file mode 100755 index 0000000..cafa63c --- /dev/null +++ b/server/scriptcraft/data/arrows-store.json @@ -0,0 +1,3 @@ +{ + "players": {} +} diff --git a/server/scriptcraft/data/classroom-store.json b/server/scriptcraft/data/classroom-store.json new file mode 100755 index 0000000..e762a2a --- /dev/null +++ b/server/scriptcraft/data/classroom-store.json @@ -0,0 +1,3 @@ +{ + "enableScripting": true +} diff --git a/server/scriptcraft/data/global-config.json b/server/scriptcraft/data/global-config.json new file mode 100755 index 0000000..95b7aee --- /dev/null +++ b/server/scriptcraft/data/global-config.json @@ -0,0 +1,3 @@ +{ + "verbose": false +} diff --git a/server/scriptcraft/data/homes-store.json b/server/scriptcraft/data/homes-store.json new file mode 100755 index 0000000..edb4e44 --- /dev/null +++ b/server/scriptcraft/data/homes-store.json @@ -0,0 +1,5 @@ +{ + "houses": {}, + "openHouses": {}, + "invites": {} +} diff --git a/server/scriptcraft/data/signs-store.json b/server/scriptcraft/data/signs-store.json new file mode 100755 index 0000000..0967ef4 --- /dev/null +++ b/server/scriptcraft/data/signs-store.json @@ -0,0 +1 @@ +{} diff --git a/server/scriptcraft/lib/command.js b/server/scriptcraft/lib/command.js new file mode 100755 index 0000000..2ba6a4d --- /dev/null +++ b/server/scriptcraft/lib/command.js @@ -0,0 +1,64 @@ +'use strict'; +/* + command management - allow for non-ops to execute approved javascript code. +*/ +var _commands = {}, + _cmdInterceptors = []; +/* + execute a JSP command. +*/ +var executeCmd = function( args, player ) { + var name, + cmd, + intercepted, + result = null; + + if ( args.length === 0 ) { + throw new Error('Usage: jsp command-name command-parameters'); + } + name = args[0]; + cmd = _commands[name]; + if ( typeof cmd === 'undefined' ) { + // it's not a global command - pass it on to interceptors + intercepted = false; + for ( var i = 0; i < _cmdInterceptors.length; i++ ) { + if ( _cmdInterceptors[i]( args, player ) ) + intercepted = true; + } + if ( !intercepted ) { + console.warn( 'Command %s is not recognised', name ); + } + }else{ + try { + result = cmd.callback( args.slice(1), player ); + } catch ( e ) { + console.error( 'Error while trying to execute command: ' + JSON.stringify( args ) ); + throw e; + } + } + return result; +}; +/* + define a new JSP command. +*/ +var defineCmd = function( name, func, options, intercepts ) { + + if ( typeof name == 'function'){ + intercepts = options; + options = func; + func = name; + name = func.name; + } + + if ( typeof options == 'undefined' ) { + options = []; + } + _commands[name] = { callback: func, options: options }; + if ( intercepts ) { + _cmdInterceptors.push(func); + } + return func; +}; +exports.command = defineCmd; +exports.commands = _commands; +exports.exec = executeCmd; diff --git a/server/scriptcraft/lib/console.js b/server/scriptcraft/lib/console.js new file mode 100755 index 0000000..854aa34 --- /dev/null +++ b/server/scriptcraft/lib/console.js @@ -0,0 +1,79 @@ +'use strict'; +/************************************************************************* +## console global variable + +ScriptCraft provides a `console` global variable with the followng methods... + + * log() + * info() + * warn() + * error() + +The ScriptCraft console methods work like the [Web API implementation][webcons]. + +### Example + + console.log('Hello %s', 'world'); + +Basic variable substitution is supported (ScriptCraft's implementation +of console uses the Bukkit Plugin [Logger][lgr] or Canary Plugin [Logman][cmlgr] under the hood and +uses [java.lang.String.format()][strfmt] for variable +substitution. All output will be sent to the server console (not +in-game). + +### Using string substitutions + +ScriptCraft uses Java's [String.format()][strfmt] so any string substitution identifiers supported by +`java.lang.String.format()` are supported (e.g. %s , %d etc). + + for (var i=0; i<5; i++) { + console.log("Hello, %s. You've called me %d times.", "Bob", i+1); + } + +[lgr]: http://jd.bukkit.org/beta/apidocs/org/bukkit/plugin/PluginLogger.html +[cmlgr]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/logger/Logman.html +[strfmt]: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#format(java.lang.String, java.lang.Object...) +[webcons]: https://developer.mozilla.org/en-US/docs/Web/API/console + +***/ +function argsToArray( args ) { + var result = []; + for ( var i =0; i < args.length; i++ ) { + result.push(args[i]); + } + return result; +} +function consMsg(params){ + var args = argsToArray(params); + if ( args.length > 1 ) { + return java.lang.String.format( args[0], args.slice(1) ); + } else { + return args[0]; + } +} + +module.exports = function(logger){ + + function bukkitLog( level, restOfArgs ) { + logger['log(java.util.logging.Level,java.lang.String)']( + java.util.logging.Level[level], + consMsg(restOfArgs) + ); + } + + if (__plugin.canary){ + return { + log: function( ) { logger.info( consMsg(arguments) ); }, + info: function( ) { logger.info( consMsg(arguments) ); }, + warn: function( ) { logger.warn( consMsg(arguments) ); }, + error: function( ) { logger.error( consMsg(arguments) ); } + }; + } else { + return { + log: function() { bukkitLog('INFO', arguments ); }, + info: function() { bukkitLog('INFO', arguments ); }, + warn: function( ) { bukkitLog('WARNING', arguments ); }, + error: function( ) { bukkitLog('SEVERE', arguments ); } + }; + } +}; diff --git a/server/scriptcraft/lib/events-bukkit.js b/server/scriptcraft/lib/events-bukkit.js new file mode 100755 index 0000000..a2577c9 --- /dev/null +++ b/server/scriptcraft/lib/events-bukkit.js @@ -0,0 +1,78 @@ +/*global Java, exports, org, __plugin */ +var bkEventPriority = org.bukkit.event.EventPriority, + bkEventExecutor = org.bukkit.plugin.EventExecutor, + bkRegisteredListener = org.bukkit.plugin.RegisteredListener, + bkEventPackage = 'org.bukkit.event.'; + +var nashorn = (typeof Java != 'undefined'); + +function getHandlerListForEventType( eventType ){ + var result = null; + var clazz = null; + if (nashorn) { + + //Nashorn doesn't like when getHandlerList is in a superclass of your event + //so to avoid this problem, call getHandlerList using java.lang.reflect + //methods + clazz = eventType['class']; + result = clazz.getMethod("getHandlerList").invoke(null); + + } else { + result = eventType.getHandlerList(); + } + + return result; +} +exports.on = function( + /* Java Class */ + eventType, + /* function( registeredListener, event) */ + handler, + /* (optional) String (HIGH, HIGHEST, LOW, LOWEST, NORMAL, MONITOR), */ + priority ) { + var handlerList, + regd, + eventExecutor; + + if ( typeof priority == 'undefined' ) { + priority = bkEventPriority.HIGHEST; + } else { + priority = bkEventPriority[priority.toUpperCase().trim()]; + } + handlerList = getHandlerListForEventType (eventType); + + var result = { }; + eventExecutor = new bkEventExecutor( { + execute: function( l, evt ) { + function cancel(){ + if (evt instanceof org.bukkit.event.Cancellable){ + evt.setCancelled(true); + } + } + /* + let handlers use this.cancel() to cancel the current event + or this.unregister() to unregister from future events. + */ + var bound = {}; + for (var i in result){ + bound[i] = result[i]; + } + bound.cancel = cancel; + handler.call( bound, evt, cancel ); + } + } ); + /* + wph 20130222 issue #64 bad interaction with Essentials plugin + if another plugin tries to unregister a Listener (not a Plugin or a RegisteredListener) + then BOOM! the other plugin will throw an error because Rhino can't coerce an + equals() method from an Interface. + The workaround is to make the ScriptCraftPlugin java class a Listener. + Should only unregister() registered plugins in ScriptCraft js code. + */ + regd = new bkRegisteredListener( __plugin, eventExecutor, priority, __plugin, true ); + handlerList.register( regd ); + result.unregister = function(){ + handlerList.unregister( regd ); + }; + return result; +}; diff --git a/server/scriptcraft/lib/events-canary.js b/server/scriptcraft/lib/events-canary.js new file mode 100755 index 0000000..59e983b --- /dev/null +++ b/server/scriptcraft/lib/events-canary.js @@ -0,0 +1,68 @@ +/*global nashorn, exports, require, Packages, __plugin*/ +var cmPriority = Packages.net.canarymod.plugin.Priority, + cmCanary = Packages.net.canarymod.Canary, + cmDispatcher = Packages.net.canarymod.hook.Dispatcher, + cmRegisteredPluginListener = Packages.net.canarymod.plugin.RegisteredPluginListener, + cmPluginListener = Packages.net.canarymod.plugin.PluginListener; +var cmHookExecutor = cmCanary.hooks(); + +exports.on = function( + /* Java Class */ + eventType, + /* function( registeredListener, event) */ + handler, + /* (optional) String (CRITICAL, HIGH, NORMAL, LOW, PASSIVE), */ + priority ) { + var handlerList, + regd, + eventExecutor; + + if ( typeof priority == 'undefined' ) { + priority = cmPriority.NORMAL; + } else { + priority = cmPriority[priority.toUpperCase().trim()]; + } + + var result = { }; + eventExecutor = __plugin.getDispatcher( function(l,e){ + function cancel(){ + if (e.setCanceled){ + e.setCanceled(); + } + } + /* + let handlers use this.cancel() to cancel the current event + or this.unregister() to unregister from future events. + */ + var bound = {}; + for (var i in result){ + bound[i] = result[i]; + } + bound.cancel = cancel; + try { + handler.call(bound, e, cancel); + } catch ( error ){ + console.log('Error while executing handler:' + handler + + ' for event type:' + eventType + + ' error: ' + error); + } + }); + /* + wph 20130222 issue #64 bad interaction with Essentials plugin + if another plugin tries to unregister a Listener (not a Plugin or a RegisteredListener) + then BOOM! the other plugin will throw an error because Rhino can't coerce an + equals() method from an Interface. + The workaround is to make the ScriptCraftPlugin java class a Listener. + Should only unregister() registered plugins in ScriptCraft js code. + */ + if (nashorn){ + // nashorn + eventType = require('nashorn-type')(eventType); + } + regd = new cmPluginListener({}); + cmHookExecutor.registerHook(regd, __plugin, eventType, eventExecutor, priority); + result.unregister = function(){ + cmHookExecutor.unregisterPluginListener(regd); + }; + return result; +}; diff --git a/server/scriptcraft/lib/events-helper-bukkit.js b/server/scriptcraft/lib/events-helper-bukkit.js new file mode 100755 index 0000000..af8bffd --- /dev/null +++ b/server/scriptcraft/lib/events-helper-bukkit.js @@ -0,0 +1,2058 @@ +/********************* +## Events Helper Module (bukkit version) +The Events helper module provides a suite of functions - one for each possible event. +For example, the events.blockBreak() function is just a wrapper function which calls events.on(org.bukkit.event.block.BlockBreakEvent, callback, priority) +This module is a convenience wrapper for easily adding new event handling functions in Javascript. +At the in-game or server-console prompt, players/admins can type `events.` and use TAB completion +to choose from any of the approx. 160 different event types to listen to. + +### Usage + + events.blockBreak( function( event ) { + echo( event.player, 'You broke a block!'); + }); + +The crucial difference is that the events module now has functions for each of the built-in events. The functions are accessible via TAB-completion so will help beginning programmers to explore the events at the server console window. + +***/ +/********************* +### events.weatherChange() + +#### Parameters + + * callback - A function which is called whenever the [weather.WeatherChangeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/weather/WeatherChangeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.weatherChange = function(callback,priority){ + return events.on(org.bukkit.event.weather.WeatherChangeEvent,callback,priority); +}; +/********************* +### events.lightningStrike() + +#### Parameters + + * callback - A function which is called whenever the [weather.LightningStrikeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/weather/LightningStrikeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.lightningStrike = function(callback,priority){ + return events.on(org.bukkit.event.weather.LightningStrikeEvent,callback,priority); +}; +/********************* +### events.thunderChange() + +#### Parameters + + * callback - A function which is called whenever the [weather.ThunderChangeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/weather/ThunderChangeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.thunderChange = function(callback,priority){ + return events.on(org.bukkit.event.weather.ThunderChangeEvent,callback,priority); +}; +/********************* +### events.vehicleMove() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleMoveEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleMoveEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleMove = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleMoveEvent,callback,priority); +}; +/********************* +### events.vehicleDestroy() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleDestroyEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleDestroyEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleDestroy = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleDestroyEvent,callback,priority); +}; +/********************* +### events.vehicleExit() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleExitEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleExitEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleExit = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleExitEvent,callback,priority); +}; +/********************* +### events.vehicleEntityCollision() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleEntityCollisionEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleEntityCollisionEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleEntityCollision = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleEntityCollisionEvent,callback,priority); +}; +/********************* +### events.vehicleBlockCollision() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleBlockCollisionEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleBlockCollision = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleBlockCollisionEvent,callback,priority); +}; +/********************* +### events.vehicleEnter() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleEnterEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleEnterEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleEnter = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleEnterEvent,callback,priority); +}; +/********************* +### events.vehicleDamage() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleDamageEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleDamageEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleDamage = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleDamageEvent,callback,priority); +}; +/********************* +### events.vehicleUpdate() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleUpdateEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleUpdateEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleUpdate = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleUpdateEvent,callback,priority); +}; +/********************* +### events.vehicleCreate() + +#### Parameters + + * callback - A function which is called whenever the [vehicle.VehicleCreateEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/vehicle/VehicleCreateEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleCreate = function(callback,priority){ + return events.on(org.bukkit.event.vehicle.VehicleCreateEvent,callback,priority); +}; +/********************* +### events.paintingBreak() + +#### Parameters + + * callback - A function which is called whenever the [painting.PaintingBreakEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/painting/PaintingBreakEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.paintingBreak = function(callback,priority){ + return events.on(org.bukkit.event.painting.PaintingBreakEvent,callback,priority); +}; +/********************* +### events.paintingBreakByEntity() + +#### Parameters + + * callback - A function which is called whenever the [painting.PaintingBreakByEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/painting/PaintingBreakByEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.paintingBreakByEntity = function(callback,priority){ + return events.on(org.bukkit.event.painting.PaintingBreakByEntityEvent,callback,priority); +}; +/********************* +### events.paintingPlace() + +#### Parameters + + * callback - A function which is called whenever the [painting.PaintingPlaceEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/painting/PaintingPlaceEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.paintingPlace = function(callback,priority){ + return events.on(org.bukkit.event.painting.PaintingPlaceEvent,callback,priority); +}; +/********************* +### events.enchantItem() + +#### Parameters + + * callback - A function which is called whenever the [enchantment.EnchantItemEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/enchantment/EnchantItemEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.enchantItem = function(callback,priority){ + return events.on(org.bukkit.event.enchantment.EnchantItemEvent,callback,priority); +}; +/********************* +### events.prepareItemEnchant() + +#### Parameters + + * callback - A function which is called whenever the [enchantment.PrepareItemEnchantEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/enchantment/PrepareItemEnchantEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.prepareItemEnchant = function(callback,priority){ + return events.on(org.bukkit.event.enchantment.PrepareItemEnchantEvent,callback,priority); +}; +/********************* +### events.playerInteractEntity() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerInteractEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerInteractEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerInteractEntity = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerInteractEntityEvent,callback,priority); +}; +/********************* +### events.playerEggThrow() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerEggThrowEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerEggThrowEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerEggThrow = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerEggThrowEvent,callback,priority); +}; +/********************* +### events.playerUnleashEntity() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerUnleashEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerUnleashEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerUnleashEntity = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerUnleashEntityEvent,callback,priority); +}; +/********************* +### events.playerInventory() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerInventoryEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerInventoryEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerInventory = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerInventoryEvent,callback,priority); +}; +/********************* +### events.playerLevelChange() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerLevelChangeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerLevelChangeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerLevelChange = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerLevelChangeEvent,callback,priority); +}; +/********************* +### events.playerPortal() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerPortalEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerPortalEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerPortal = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerPortalEvent,callback,priority); +}; +/********************* +### events.playerItemConsume() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerItemConsumeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerItemConsumeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerItemConsume = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerItemConsumeEvent,callback,priority); +}; +/********************* +### events.playerTeleport() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerTeleportEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerTeleportEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerTeleport = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerTeleportEvent,callback,priority); +}; +/********************* +### events.playerBedEnter() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerBedEnterEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerBedEnterEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerBedEnter = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerBedEnterEvent,callback,priority); +}; +/********************* +### events.playerUnregisterChannel() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerUnregisterChannelEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerUnregisterChannelEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerUnregisterChannel = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerUnregisterChannelEvent,callback,priority); +}; +/********************* +### events.playerChat() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerChatEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerChatEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerChat = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerChatEvent,callback,priority); +}; +/********************* +### events.playerShearEntity() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerShearEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerShearEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerShearEntity = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerShearEntityEvent,callback,priority); +}; +/********************* +### events.asyncPlayerChat() + +#### Parameters + + * callback - A function which is called whenever the [player.AsyncPlayerChatEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/AsyncPlayerChatEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.asyncPlayerChat = function(callback,priority){ + return events.on(org.bukkit.event.player.AsyncPlayerChatEvent,callback,priority); +}; +/********************* +### events.playerDropItem() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerDropItemEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerDropItemEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerDropItem = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerDropItemEvent,callback,priority); +}; +/********************* +### events.playerRegisterChannel() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerRegisterChannelEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerRegisterChannelEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerRegisterChannel = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerRegisterChannelEvent,callback,priority); +}; +/********************* +### events.playerMove() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerMoveEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerMoveEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerMove = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerMoveEvent,callback,priority); +}; +/********************* +### events.playerItemBreak() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerItemBreakEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerItemBreakEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerItemBreak = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerItemBreakEvent,callback,priority); +}; +/********************* +### events.playerBucketEmpty() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerBucketEmptyEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerBucketEmptyEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerBucketEmpty = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerBucketEmptyEvent,callback,priority); +}; +/********************* +### events.playerStatisticIncrement() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerStatisticIncrementEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerStatisticIncrementEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerStatisticIncrement = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerStatisticIncrementEvent,callback,priority); +}; +/********************* +### events.playerToggleFlight() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerToggleFlightEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerToggleFlightEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerToggleFlight = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerToggleFlightEvent,callback,priority); +}; +/********************* +### events.playerItemHeld() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerItemHeldEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerItemHeldEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerItemHeld = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerItemHeldEvent,callback,priority); +}; +/********************* +### events.playerAchievementAwarded() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerAchievementAwardedEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerAchievementAwardedEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerAchievementAwarded = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerAchievementAwardedEvent,callback,priority); +}; +/********************* +### events.playerToggleSneak() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerToggleSneakEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerToggleSneakEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerToggleSneak = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerToggleSneakEvent,callback,priority); +}; +/********************* +### events.playerExpChange() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerExpChangeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerExpChangeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerExpChange = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerExpChangeEvent,callback,priority); +}; +/********************* +### events.playerPreLogin() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerPreLoginEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerPreLoginEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerPreLogin = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerPreLoginEvent,callback,priority); +}; +/********************* +### events.playerJoin() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerJoinEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerJoinEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerJoin = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerJoinEvent,callback,priority); +}; +/********************* +### events.playerAnimation() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerAnimationEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerAnimationEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerAnimation = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerAnimationEvent,callback,priority); +}; +/********************* +### events.playerEditBook() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerEditBookEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerEditBookEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerEditBook = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerEditBookEvent,callback,priority); +}; +/********************* +### events.playerPickupItem() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerPickupItemEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerPickupItemEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerPickupItem = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerPickupItemEvent,callback,priority); +}; +/********************* +### events.playerChangedWorld() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerChangedWorldEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerChangedWorldEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerChangedWorld = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerChangedWorldEvent,callback,priority); +}; +/********************* +### events.playerFish() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerFishEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerFishEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerFish = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerFishEvent,callback,priority); +}; +/********************* +### events.playerChatTabComplete() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerChatTabCompleteEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerChatTabCompleteEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerChatTabComplete = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerChatTabCompleteEvent,callback,priority); +}; +/********************* +### events.playerRespawn() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerRespawnEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerRespawnEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerRespawn = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerRespawnEvent,callback,priority); +}; +/********************* +### events.playerBedLeave() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerBedLeaveEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerBedLeaveEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerBedLeave = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerBedLeaveEvent,callback,priority); +}; +/********************* +### events.asyncPlayerPreLogin() + +#### Parameters + + * callback - A function which is called whenever the [player.AsyncPlayerPreLoginEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/AsyncPlayerPreLoginEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.asyncPlayerPreLogin = function(callback,priority){ + return events.on(org.bukkit.event.player.AsyncPlayerPreLoginEvent,callback,priority); +}; +/********************* +### events.playerInteract() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerInteractEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerInteractEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerInteract = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerInteractEvent,callback,priority); +}; +/********************* +### events.playerBucketFill() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerBucketFillEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerBucketFillEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerBucketFill = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerBucketFillEvent,callback,priority); +}; +/********************* +### events.playerVelocity() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerVelocityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerVelocityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerVelocity = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerVelocityEvent,callback,priority); +}; +/********************* +### events.playerQuit() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerQuitEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerQuitEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerQuit = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerQuitEvent,callback,priority); +}; +/********************* +### events.playerLogin() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerLoginEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerLoginEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerLogin = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerLoginEvent,callback,priority); +}; +/********************* +### events.playerKick() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerKickEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerKickEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerKick = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerKickEvent,callback,priority); +}; +/********************* +### events.playerToggleSprint() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerToggleSprintEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerToggleSprintEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerToggleSprint = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerToggleSprintEvent,callback,priority); +}; +/********************* +### events.playerCommandPreprocess() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerCommandPreprocessEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerCommandPreprocessEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerCommandPreprocess = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerCommandPreprocessEvent,callback,priority); +}; +/********************* +### events.playerGameModeChange() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerGameModeChangeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/player/PlayerGameModeChangeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerGameModeChange = function(callback,priority){ + return events.on(org.bukkit.event.player.PlayerGameModeChangeEvent,callback,priority); +}; +/********************* +### events.furnaceSmelt() + +#### Parameters + + * callback - A function which is called whenever the [inventory.FurnaceSmeltEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/FurnaceSmeltEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.furnaceSmelt = function(callback,priority){ + return events.on(org.bukkit.event.inventory.FurnaceSmeltEvent,callback,priority); +}; +/********************* +### events.inventoryDrag() + +#### Parameters + + * callback - A function which is called whenever the [inventory.InventoryDragEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/InventoryDragEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventoryDrag = function(callback,priority){ + return events.on(org.bukkit.event.inventory.InventoryDragEvent,callback,priority); +}; +/********************* +### events.craftItem() + +#### Parameters + + * callback - A function which is called whenever the [inventory.CraftItemEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/CraftItemEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.craftItem = function(callback,priority){ + return events.on(org.bukkit.event.inventory.CraftItemEvent,callback,priority); +}; +/********************* +### events.furnaceBurn() + +#### Parameters + + * callback - A function which is called whenever the [inventory.FurnaceBurnEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/FurnaceBurnEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.furnaceBurn = function(callback,priority){ + return events.on(org.bukkit.event.inventory.FurnaceBurnEvent,callback,priority); +}; +/********************* +### events.inventoryOpen() + +#### Parameters + + * callback - A function which is called whenever the [inventory.InventoryOpenEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/InventoryOpenEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventoryOpen = function(callback,priority){ + return events.on(org.bukkit.event.inventory.InventoryOpenEvent,callback,priority); +}; +/********************* +### events.inventoryPickupItem() + +#### Parameters + + * callback - A function which is called whenever the [inventory.InventoryPickupItemEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/InventoryPickupItemEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventoryPickupItem = function(callback,priority){ + return events.on(org.bukkit.event.inventory.InventoryPickupItemEvent,callback,priority); +}; +/********************* +### events.inventoryMoveItem() + +#### Parameters + + * callback - A function which is called whenever the [inventory.InventoryMoveItemEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/InventoryMoveItemEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventoryMoveItem = function(callback,priority){ + return events.on(org.bukkit.event.inventory.InventoryMoveItemEvent,callback,priority); +}; +/********************* +### events.inventoryClick() + +#### Parameters + + * callback - A function which is called whenever the [inventory.InventoryClickEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/InventoryClickEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventoryClick = function(callback,priority){ + return events.on(org.bukkit.event.inventory.InventoryClickEvent,callback,priority); +}; +/********************* +### events.inventoryClose() + +#### Parameters + + * callback - A function which is called whenever the [inventory.InventoryCloseEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/InventoryCloseEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventoryClose = function(callback,priority){ + return events.on(org.bukkit.event.inventory.InventoryCloseEvent,callback,priority); +}; +/********************* +### events.inventoryCreative() + +#### Parameters + + * callback - A function which is called whenever the [inventory.InventoryCreativeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/InventoryCreativeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventoryCreative = function(callback,priority){ + return events.on(org.bukkit.event.inventory.InventoryCreativeEvent,callback,priority); +}; +/********************* +### events.inventory() + +#### Parameters + + * callback - A function which is called whenever the [inventory.InventoryEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/InventoryEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventory = function(callback,priority){ + return events.on(org.bukkit.event.inventory.InventoryEvent,callback,priority); +}; +/********************* +### events.prepareItemCraft() + +#### Parameters + + * callback - A function which is called whenever the [inventory.PrepareItemCraftEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/PrepareItemCraftEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.prepareItemCraft = function(callback,priority){ + return events.on(org.bukkit.event.inventory.PrepareItemCraftEvent,callback,priority); +}; +/********************* +### events.furnaceExtract() + +#### Parameters + + * callback - A function which is called whenever the [inventory.FurnaceExtractEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/FurnaceExtractEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.furnaceExtract = function(callback,priority){ + return events.on(org.bukkit.event.inventory.FurnaceExtractEvent,callback,priority); +}; +/********************* +### events.brew() + +#### Parameters + + * callback - A function which is called whenever the [inventory.BrewEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/inventory/BrewEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.brew = function(callback,priority){ + return events.on(org.bukkit.event.inventory.BrewEvent,callback,priority); +}; +/********************* +### events.serverCommand() + +#### Parameters + + * callback - A function which is called whenever the [server.ServerCommandEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/server/ServerCommandEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.serverCommand = function(callback,priority){ + return events.on(org.bukkit.event.server.ServerCommandEvent,callback,priority); +}; +/********************* +### events.serverListPing() + +#### Parameters + + * callback - A function which is called whenever the [server.ServerListPingEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/server/ServerListPingEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.serverListPing = function(callback,priority){ + return events.on(org.bukkit.event.server.ServerListPingEvent,callback,priority); +}; +/********************* +### events.serviceRegister() + +#### Parameters + + * callback - A function which is called whenever the [server.ServiceRegisterEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/server/ServiceRegisterEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.serviceRegister = function(callback,priority){ + return events.on(org.bukkit.event.server.ServiceRegisterEvent,callback,priority); +}; +/********************* +### events.pluginDisable() + +#### Parameters + + * callback - A function which is called whenever the [server.PluginDisableEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/server/PluginDisableEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.pluginDisable = function(callback,priority){ + return events.on(org.bukkit.event.server.PluginDisableEvent,callback,priority); +}; +/********************* +### events.remoteServerCommand() + +#### Parameters + + * callback - A function which is called whenever the [server.RemoteServerCommandEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/server/RemoteServerCommandEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.remoteServerCommand = function(callback,priority){ + return events.on(org.bukkit.event.server.RemoteServerCommandEvent,callback,priority); +}; +/********************* +### events.mapInitialize() + +#### Parameters + + * callback - A function which is called whenever the [server.MapInitializeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/server/MapInitializeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.mapInitialize = function(callback,priority){ + return events.on(org.bukkit.event.server.MapInitializeEvent,callback,priority); +}; +/********************* +### events.serviceUnregister() + +#### Parameters + + * callback - A function which is called whenever the [server.ServiceUnregisterEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/server/ServiceUnregisterEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.serviceUnregister = function(callback,priority){ + return events.on(org.bukkit.event.server.ServiceUnregisterEvent,callback,priority); +}; +/********************* +### events.pluginEnable() + +#### Parameters + + * callback - A function which is called whenever the [server.PluginEnableEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/server/PluginEnableEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.pluginEnable = function(callback,priority){ + return events.on(org.bukkit.event.server.PluginEnableEvent,callback,priority); +}; +/********************* +### events.playerDeath() + +#### Parameters + + * callback - A function which is called whenever the [entity.PlayerDeathEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/PlayerDeathEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerDeath = function(callback,priority){ + return events.on(org.bukkit.event.entity.PlayerDeathEvent,callback,priority); +}; +/********************* +### events.entityCreatePortal() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityCreatePortalEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityCreatePortalEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityCreatePortal = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityCreatePortalEvent,callback,priority); +}; +/********************* +### events.entityCombust() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityCombustEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityCombustEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityCombust = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityCombustEvent,callback,priority); +}; +/********************* +### events.sheepDyeWool() + +#### Parameters + + * callback - A function which is called whenever the [entity.SheepDyeWoolEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/SheepDyeWoolEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.sheepDyeWool = function(callback,priority){ + return events.on(org.bukkit.event.entity.SheepDyeWoolEvent,callback,priority); +}; +/********************* +### events.expBottle() + +#### Parameters + + * callback - A function which is called whenever the [entity.ExpBottleEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/ExpBottleEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.expBottle = function(callback,priority){ + return events.on(org.bukkit.event.entity.ExpBottleEvent,callback,priority); +}; +/********************* +### events.entityTame() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityTameEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityTameEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityTame = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityTameEvent,callback,priority); +}; +/********************* +### events.projectileLaunch() + +#### Parameters + + * callback - A function which is called whenever the [entity.ProjectileLaunchEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/ProjectileLaunchEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.projectileLaunch = function(callback,priority){ + return events.on(org.bukkit.event.entity.ProjectileLaunchEvent,callback,priority); +}; +/********************* +### events.entityDamage() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityDamageEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityDamageEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityDamage = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityDamageEvent,callback,priority); +}; +/********************* +### events.itemSpawn() + +#### Parameters + + * callback - A function which is called whenever the [entity.ItemSpawnEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/ItemSpawnEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.itemSpawn = function(callback,priority){ + return events.on(org.bukkit.event.entity.ItemSpawnEvent,callback,priority); +}; +/********************* +### events.projectileHit() + +#### Parameters + + * callback - A function which is called whenever the [entity.ProjectileHitEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/ProjectileHitEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.projectileHit = function(callback,priority){ + return events.on(org.bukkit.event.entity.ProjectileHitEvent,callback,priority); +}; +/********************* +### events.foodLevelChange() + +#### Parameters + + * callback - A function which is called whenever the [entity.FoodLevelChangeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/FoodLevelChangeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.foodLevelChange = function(callback,priority){ + return events.on(org.bukkit.event.entity.FoodLevelChangeEvent,callback,priority); +}; +/********************* +### events.itemDespawn() + +#### Parameters + + * callback - A function which is called whenever the [entity.ItemDespawnEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/ItemDespawnEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.itemDespawn = function(callback,priority){ + return events.on(org.bukkit.event.entity.ItemDespawnEvent,callback,priority); +}; +/********************* +### events.entityPortalEnter() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityPortalEnterEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityPortalEnterEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityPortalEnter = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityPortalEnterEvent,callback,priority); +}; +/********************* +### events.entityPortal() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityPortalEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityPortalEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityPortal = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityPortalEvent,callback,priority); +}; +/********************* +### events.entityTarget() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityTargetEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityTargetEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityTarget = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityTargetEvent,callback,priority); +}; +/********************* +### events.entityDeath() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityDeathEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityDeathEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityDeath = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityDeathEvent,callback,priority); +}; +/********************* +### events.sheepRegrowWool() + +#### Parameters + + * callback - A function which is called whenever the [entity.SheepRegrowWoolEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/SheepRegrowWoolEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.sheepRegrowWool = function(callback,priority){ + return events.on(org.bukkit.event.entity.SheepRegrowWoolEvent,callback,priority); +}; +/********************* +### events.entityShootBow() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityShootBowEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityShootBowEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityShootBow = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityShootBowEvent,callback,priority); +}; +/********************* +### events.creeperPower() + +#### Parameters + + * callback - A function which is called whenever the [entity.CreeperPowerEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/CreeperPowerEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.creeperPower = function(callback,priority){ + return events.on(org.bukkit.event.entity.CreeperPowerEvent,callback,priority); +}; +/********************* +### events.entityCombustByBlock() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityCombustByBlockEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityCombustByBlockEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityCombustByBlock = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityCombustByBlockEvent,callback,priority); +}; +/********************* +### events.entityBreakDoor() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityBreakDoorEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityBreakDoorEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityBreakDoor = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityBreakDoorEvent,callback,priority); +}; +/********************* +### events.entityDamageByEntity() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityDamageByEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityDamageByEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityDamageByEntity = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityDamageByEntityEvent,callback,priority); +}; +/********************* +### events.entityUnleash() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityUnleashEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityUnleashEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityUnleash = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityUnleashEvent,callback,priority); +}; +/********************* +### events.entityExplode() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityExplodeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityExplodeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityExplode = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityExplodeEvent,callback,priority); +}; +/********************* +### events.entityInteract() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityInteractEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityInteractEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityInteract = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityInteractEvent,callback,priority); +}; +/********************* +### events.explosionPrime() + +#### Parameters + + * callback - A function which is called whenever the [entity.ExplosionPrimeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/ExplosionPrimeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.explosionPrime = function(callback,priority){ + return events.on(org.bukkit.event.entity.ExplosionPrimeEvent,callback,priority); +}; +/********************* +### events.horseJump() + +#### Parameters + + * callback - A function which is called whenever the [entity.HorseJumpEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/HorseJumpEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.horseJump = function(callback,priority){ + return events.on(org.bukkit.event.entity.HorseJumpEvent,callback,priority); +}; +/********************* +### events.creatureSpawn() + +#### Parameters + + * callback - A function which is called whenever the [entity.CreatureSpawnEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/CreatureSpawnEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.creatureSpawn = function(callback,priority){ + return events.on(org.bukkit.event.entity.CreatureSpawnEvent,callback,priority); +}; +/********************* +### events.entityCombustByEntity() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityCombustByEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityCombustByEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityCombustByEntity = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityCombustByEntityEvent,callback,priority); +}; +/********************* +### events.entityDamageByBlock() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityDamageByBlockEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityDamageByBlockEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityDamageByBlock = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityDamageByBlockEvent,callback,priority); +}; +/********************* +### events.entityTargetLivingEntity() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityTargetLivingEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityTargetLivingEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityTargetLivingEntity = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityTargetLivingEntityEvent,callback,priority); +}; +/********************* +### events.entityTeleport() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityTeleportEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityTeleportEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityTeleport = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityTeleportEvent,callback,priority); +}; +/********************* +### events.playerLeashEntity() + +#### Parameters + + * callback - A function which is called whenever the [entity.PlayerLeashEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/PlayerLeashEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerLeashEntity = function(callback,priority){ + return events.on(org.bukkit.event.entity.PlayerLeashEntityEvent,callback,priority); +}; +/********************* +### events.slimeSplit() + +#### Parameters + + * callback - A function which is called whenever the [entity.SlimeSplitEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/SlimeSplitEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.slimeSplit = function(callback,priority){ + return events.on(org.bukkit.event.entity.SlimeSplitEvent,callback,priority); +}; +/********************* +### events.pigZap() + +#### Parameters + + * callback - A function which is called whenever the [entity.PigZapEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/PigZapEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.pigZap = function(callback,priority){ + return events.on(org.bukkit.event.entity.PigZapEvent,callback,priority); +}; +/********************* +### events.potionSplash() + +#### Parameters + + * callback - A function which is called whenever the [entity.PotionSplashEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/PotionSplashEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.potionSplash = function(callback,priority){ + return events.on(org.bukkit.event.entity.PotionSplashEvent,callback,priority); +}; +/********************* +### events.entityChangeBlock() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityChangeBlockEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityChangeBlockEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityChangeBlock = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityChangeBlockEvent,callback,priority); +}; +/********************* +### events.entityPortalExit() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityPortalExitEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityPortalExitEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityPortalExit = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityPortalExitEvent,callback,priority); +}; +/********************* +### events.entityRegainHealth() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityRegainHealthEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/entity/EntityRegainHealthEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityRegainHealth = function(callback,priority){ + return events.on(org.bukkit.event.entity.EntityRegainHealthEvent,callback,priority); +}; +/********************* +### events.entityBlockForm() + +#### Parameters + + * callback - A function which is called whenever the [block.EntityBlockFormEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/EntityBlockFormEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityBlockForm = function(callback,priority){ + return events.on(org.bukkit.event.block.EntityBlockFormEvent,callback,priority); +}; +/********************* +### events.blockSpread() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockSpreadEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockSpreadEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockSpread = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockSpreadEvent,callback,priority); +}; +/********************* +### events.blockMultiPlace() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockMultiPlaceEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockMultiPlaceEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockMultiPlace = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockMultiPlaceEvent,callback,priority); +}; +/********************* +### events.notePlay() + +#### Parameters + + * callback - A function which is called whenever the [block.NotePlayEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/NotePlayEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.notePlay = function(callback,priority){ + return events.on(org.bukkit.event.block.NotePlayEvent,callback,priority); +}; +/********************* +### events.blockFade() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockFadeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockFadeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockFade = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockFadeEvent,callback,priority); +}; +/********************* +### events.blockPlace() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockPlaceEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockPlaceEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockPlace = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockPlaceEvent,callback,priority); +}; +/********************* +### events.blockPhysics() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockPhysicsEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockPhysicsEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockPhysics = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockPhysicsEvent,callback,priority); +}; +/********************* +### events.blockIgnite() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockIgniteEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockIgniteEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockIgnite = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockIgniteEvent,callback,priority); +}; +/********************* +### events.blockBreak() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockBreakEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockBreakEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockBreak = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockBreakEvent,callback,priority); +}; +/********************* +### events.blockBurn() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockBurnEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockBurnEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockBurn = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockBurnEvent,callback,priority); +}; +/********************* +### events.blockFromTo() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockFromToEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockFromToEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockFromTo = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockFromToEvent,callback,priority); +}; +/********************* +### events.blockRedstone() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockRedstoneEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockRedstoneEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockRedstone = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockRedstoneEvent,callback,priority); +}; +/********************* +### events.blockPistonRetract() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockPistonRetractEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockPistonRetractEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockPistonRetract = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockPistonRetractEvent,callback,priority); +}; +/********************* +### events.blockDispense() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockDispenseEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockDispenseEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockDispense = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockDispenseEvent,callback,priority); +}; +/********************* +### events.signChange() + +#### Parameters + + * callback - A function which is called whenever the [block.SignChangeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/SignChangeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.signChange = function(callback,priority){ + return events.on(org.bukkit.event.block.SignChangeEvent,callback,priority); +}; +/********************* +### events.blockPistonExtend() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockPistonExtendEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockPistonExtendEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockPistonExtend = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockPistonExtendEvent,callback,priority); +}; +/********************* +### events.blockCanBuild() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockCanBuildEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockCanBuildEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockCanBuild = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockCanBuildEvent,callback,priority); +}; +/********************* +### events.blockGrow() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockGrowEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockGrowEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockGrow = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockGrowEvent,callback,priority); +}; +/********************* +### events.leavesDecay() + +#### Parameters + + * callback - A function which is called whenever the [block.LeavesDecayEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/LeavesDecayEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.leavesDecay = function(callback,priority){ + return events.on(org.bukkit.event.block.LeavesDecayEvent,callback,priority); +}; +/********************* +### events.blockExp() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockExpEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockExpEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockExp = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockExpEvent,callback,priority); +}; +/********************* +### events.blockForm() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockFormEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockFormEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockForm = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockFormEvent,callback,priority); +}; +/********************* +### events.blockDamage() + +#### Parameters + + * callback - A function which is called whenever the [block.BlockDamageEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/block/BlockDamageEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockDamage = function(callback,priority){ + return events.on(org.bukkit.event.block.BlockDamageEvent,callback,priority); +}; +/********************* +### events.hangingPlace() + +#### Parameters + + * callback - A function which is called whenever the [hanging.HangingPlaceEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/hanging/HangingPlaceEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.hangingPlace = function(callback,priority){ + return events.on(org.bukkit.event.hanging.HangingPlaceEvent,callback,priority); +}; +/********************* +### events.hangingBreakByEntity() + +#### Parameters + + * callback - A function which is called whenever the [hanging.HangingBreakByEntityEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/hanging/HangingBreakByEntityEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.hangingBreakByEntity = function(callback,priority){ + return events.on(org.bukkit.event.hanging.HangingBreakByEntityEvent,callback,priority); +}; +/********************* +### events.hangingBreak() + +#### Parameters + + * callback - A function which is called whenever the [hanging.HangingBreakEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/hanging/HangingBreakEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.hangingBreak = function(callback,priority){ + return events.on(org.bukkit.event.hanging.HangingBreakEvent,callback,priority); +}; +/********************* +### events.structureGrow() + +#### Parameters + + * callback - A function which is called whenever the [world.StructureGrowEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/StructureGrowEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.structureGrow = function(callback,priority){ + return events.on(org.bukkit.event.world.StructureGrowEvent,callback,priority); +}; +/********************* +### events.spawnChange() + +#### Parameters + + * callback - A function which is called whenever the [world.SpawnChangeEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/SpawnChangeEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.spawnChange = function(callback,priority){ + return events.on(org.bukkit.event.world.SpawnChangeEvent,callback,priority); +}; +/********************* +### events.worldLoad() + +#### Parameters + + * callback - A function which is called whenever the [world.WorldLoadEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/WorldLoadEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.worldLoad = function(callback,priority){ + return events.on(org.bukkit.event.world.WorldLoadEvent,callback,priority); +}; +/********************* +### events.worldInit() + +#### Parameters + + * callback - A function which is called whenever the [world.WorldInitEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/WorldInitEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.worldInit = function(callback,priority){ + return events.on(org.bukkit.event.world.WorldInitEvent,callback,priority); +}; +/********************* +### events.worldUnload() + +#### Parameters + + * callback - A function which is called whenever the [world.WorldUnloadEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/WorldUnloadEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.worldUnload = function(callback,priority){ + return events.on(org.bukkit.event.world.WorldUnloadEvent,callback,priority); +}; +/********************* +### events.worldSave() + +#### Parameters + + * callback - A function which is called whenever the [world.WorldSaveEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/WorldSaveEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.worldSave = function(callback,priority){ + return events.on(org.bukkit.event.world.WorldSaveEvent,callback,priority); +}; +/********************* +### events.chunkUnload() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkUnloadEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/ChunkUnloadEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chunkUnload = function(callback,priority){ + return events.on(org.bukkit.event.world.ChunkUnloadEvent,callback,priority); +}; +/********************* +### events.chunkPopulate() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkPopulateEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/ChunkPopulateEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chunkPopulate = function(callback,priority){ + return events.on(org.bukkit.event.world.ChunkPopulateEvent,callback,priority); +}; +/********************* +### events.portalCreate() + +#### Parameters + + * callback - A function which is called whenever the [world.PortalCreateEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/PortalCreateEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.portalCreate = function(callback,priority){ + return events.on(org.bukkit.event.world.PortalCreateEvent,callback,priority); +}; +/********************* +### events.chunkLoad() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkLoadEvent event](http://jd.bukkit.org/rb/apidocs/org/bukkit/event/world/ChunkLoadEvent.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chunkLoad = function(callback,priority){ + return events.on(org.bukkit.event.world.ChunkLoadEvent,callback,priority); +}; diff --git a/server/scriptcraft/lib/events-helper-canary.js b/server/scriptcraft/lib/events-helper-canary.js new file mode 100755 index 0000000..8f4a2ed --- /dev/null +++ b/server/scriptcraft/lib/events-helper-canary.js @@ -0,0 +1,1564 @@ +/********************* +## Events Helper Module (canary version) +The Events helper module provides a suite of functions - one for each possible event. +For example, the events.blockDestroy() function is just a wrapper function which calls events.on(net.canarymod.hook.player.BlockDestroyHook, callback, priority) +This module is a convenience wrapper for easily adding new event handling functions in Javascript. +At the in-game or server-console prompt, players/admins can type `events.` and use TAB completion +to choose from any of the approx. 160 different event types to listen to. + +### Usage + + events.blockDestroy( function( event ) { + echo( event.player, 'You broke a block!'); + }); + +The crucial difference is that the events module now has functions for each of the built-in events. The functions are accessible via TAB-completion so will help beginning programmers to explore the events at the server console window. + +***/ +/********************* +### events.minecartActivate() + +#### Parameters + + * callback - A function which is called whenever the [entity.MinecartActivateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/MinecartActivateHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.minecartActivate = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.MinecartActivateHook,callback,priority); +}; +/********************* +### events.villagerTradeUnlock() + +#### Parameters + + * callback - A function which is called whenever the [entity.VillagerTradeUnlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VillagerTradeUnlockHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.villagerTradeUnlock = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.VillagerTradeUnlockHook,callback,priority); +}; +/********************* +### events.mobTarget() + +#### Parameters + + * callback - A function which is called whenever the [entity.MobTargetHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/MobTargetHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.mobTarget = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.MobTargetHook,callback,priority); +}; +/********************* +### events.chickenLayEgg() + +#### Parameters + + * callback - A function which is called whenever the [entity.ChickenLayEggHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ChickenLayEggHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chickenLayEgg = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.ChickenLayEggHook,callback,priority); +}; +/********************* +### events.potionEffectFinish() + +#### Parameters + + * callback - A function which is called whenever the [entity.PotionEffectFinishHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/PotionEffectFinishHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.potionEffectFinish = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.PotionEffectFinishHook,callback,priority); +}; +/********************* +### events.entityMove() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityMoveHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityMove = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EntityMoveHook,callback,priority); +}; +/********************* +### events.hangingEntityDestroy() + +#### Parameters + + * callback - A function which is called whenever the [entity.HangingEntityDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/HangingEntityDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.hangingEntityDestroy = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.HangingEntityDestroyHook,callback,priority); +}; +/********************* +### events.vehicleCollision() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleCollisionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleCollisionHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleCollision = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.VehicleCollisionHook,callback,priority); +}; +/********************* +### events.potionEffectApplied() + +#### Parameters + + * callback - A function which is called whenever the [entity.PotionEffectAppliedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/PotionEffectAppliedHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.potionEffectApplied = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.PotionEffectAppliedHook,callback,priority); +}; +/********************* +### events.vehicleDestroy() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleDestroy = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.VehicleDestroyHook,callback,priority); +}; +/********************* +### events.vehicleEnter() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleEnterHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleEnterHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleEnter = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.VehicleEnterHook,callback,priority); +}; +/********************* +### events.damage() + +#### Parameters + + * callback - A function which is called whenever the [entity.DamageHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/DamageHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.damage = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.DamageHook,callback,priority); +}; +/********************* +### events.entityMount() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityMountHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityMountHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityMount = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EntityMountHook,callback,priority); +}; +/********************* +### events.slimeSplit() + +#### Parameters + + * callback - A function which is called whenever the [entity.SlimeSplitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/SlimeSplitHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.slimeSplit = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.SlimeSplitHook,callback,priority); +}; +/********************* +### events.endermanDropBlock() + +#### Parameters + + * callback - A function which is called whenever the [entity.EndermanDropBlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EndermanDropBlockHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.endermanDropBlock = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EndermanDropBlockHook,callback,priority); +}; +/********************* +### events.itemTouchGround() + +#### Parameters + + * callback - A function which is called whenever the [entity.ItemTouchGroundHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ItemTouchGroundHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.itemTouchGround = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.ItemTouchGroundHook,callback,priority); +}; +/********************* +### events.entitySpawn() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntitySpawnHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntitySpawnHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entitySpawn = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EntitySpawnHook,callback,priority); +}; +/********************* +### events.endermanPickupBlock() + +#### Parameters + + * callback - A function which is called whenever the [entity.EndermanPickupBlockHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EndermanPickupBlockHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.endermanPickupBlock = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EndermanPickupBlockHook,callback,priority); +}; +/********************* +### events.vehicleDamage() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleDamageHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleDamageHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleDamage = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.VehicleDamageHook,callback,priority); +}; +/********************* +### events.entityLightningStruck() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityLightningStruckHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityLightningStruckHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityLightningStruck = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EntityLightningStruckHook,callback,priority); +}; +/********************* +### events.entityDespawn() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityDespawnHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityDespawnHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityDespawn = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EntityDespawnHook,callback,priority); +}; +/********************* +### events.vehicleMove() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleMoveHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleMove = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.VehicleMoveHook,callback,priority); +}; +/********************* +### events.projectileHit() + +#### Parameters + + * callback - A function which is called whenever the [entity.ProjectileHitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/ProjectileHitHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.projectileHit = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.ProjectileHitHook,callback,priority); +}; +/********************* +### events.entityDeath() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityDeathHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityDeathHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityDeath = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EntityDeathHook,callback,priority); +}; +/********************* +### events.entityTame() + +#### Parameters + + * callback - A function which is called whenever the [entity.EntityTameHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/EntityTameHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityTame = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.EntityTameHook,callback,priority); +}; +/********************* +### events.vehicleExit() + +#### Parameters + + * callback - A function which is called whenever the [entity.VehicleExitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/VehicleExitHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.vehicleExit = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.VehicleExitHook,callback,priority); +}; +/********************* +### events.dimensionSwitch() + +#### Parameters + + * callback - A function which is called whenever the [entity.DimensionSwitchHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/entity/DimensionSwitchHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.dimensionSwitch = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.entity.DimensionSwitchHook,callback,priority); +}; +/********************* +### events.foodLevel() + +#### Parameters + + * callback - A function which is called whenever the [player.FoodLevelHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodLevelHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.foodLevel = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.FoodLevelHook,callback,priority); +}; +/********************* +### events.bookEdit() + +#### Parameters + + * callback - A function which is called whenever the [player.BookEditHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BookEditHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.bookEdit = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.BookEditHook,callback,priority); +}; +/********************* +### events.eat() + +#### Parameters + + * callback - A function which is called whenever the [player.EatHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EatHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.eat = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.EatHook,callback,priority); +}; +/********************* +### events.playerList() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerListHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerListHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerList = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PlayerListHook,callback,priority); +}; +/********************* +### events.playerIdle() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerIdleHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerIdleHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerIdle = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PlayerIdleHook,callback,priority); +}; +/********************* +### events.enchant() + +#### Parameters + + * callback - A function which is called whenever the [player.EnchantHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EnchantHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.enchant = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.EnchantHook,callback,priority); +}; +/********************* +### events.playerArmSwing() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerArmSwingHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerArmSwingHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerArmSwing = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PlayerArmSwingHook,callback,priority); +}; +/********************* +### events.teleport() + +#### Parameters + + * callback - A function which is called whenever the [player.TeleportHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/TeleportHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.teleport = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.TeleportHook,callback,priority); +}; +/********************* +### events.anvilUse() + +#### Parameters + + * callback - A function which is called whenever the [player.AnvilUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/AnvilUseHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.anvilUse = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.AnvilUseHook,callback,priority); +}; +/********************* +### events.portalUse() + +#### Parameters + + * callback - A function which is called whenever the [player.PortalUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PortalUseHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.portalUse = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PortalUseHook,callback,priority); +}; +/********************* +### events.foodSaturation() + +#### Parameters + + * callback - A function which is called whenever the [player.FoodSaturationHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodSaturationHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.foodSaturation = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.FoodSaturationHook,callback,priority); +}; +/********************* +### events.connection() + +#### Parameters + + * callback - A function which is called whenever the [player.ConnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ConnectionHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.connection = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ConnectionHook,callback,priority); +}; +/********************* +### events.playerRespawned() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerRespawnedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerRespawnedHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerRespawned = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PlayerRespawnedHook,callback,priority); +}; +/********************* +### events.armorBroken() + +#### Parameters + + * callback - A function which is called whenever the [player.ArmorBrokenHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ArmorBrokenHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.armorBroken = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ArmorBrokenHook,callback,priority); +}; +/********************* +### events.levelUp() + +#### Parameters + + * callback - A function which is called whenever the [player.LevelUpHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/LevelUpHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.levelUp = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.LevelUpHook,callback,priority); +}; +/********************* +### events.blockRightClick() + +#### Parameters + + * callback - A function which is called whenever the [player.BlockRightClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockRightClickHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockRightClick = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.BlockRightClickHook,callback,priority); +}; +/********************* +### events.itemDrop() + +#### Parameters + + * callback - A function which is called whenever the [player.ItemDropHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemDropHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.itemDrop = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ItemDropHook,callback,priority); +}; +/********************* +### events.itemFrameRotate() + +#### Parameters + + * callback - A function which is called whenever the [player.ItemFrameRotateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemFrameRotateHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.itemFrameRotate = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ItemFrameRotateHook,callback,priority); +}; +/********************* +### events.playerRespawning() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerRespawningHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerRespawningHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerRespawning = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PlayerRespawningHook,callback,priority); +}; +/********************* +### events.craft() + +#### Parameters + + * callback - A function which is called whenever the [player.CraftHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/CraftHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.craft = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.CraftHook,callback,priority); +}; +/********************* +### events.experience() + +#### Parameters + + * callback - A function which is called whenever the [player.ExperienceHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ExperienceHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.experience = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ExperienceHook,callback,priority); +}; +/********************* +### events.signChange() + +#### Parameters + + * callback - A function which is called whenever the [player.SignChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SignChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.signChange = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.SignChangeHook,callback,priority); +}; +/********************* +### events.healthChange() + +#### Parameters + + * callback - A function which is called whenever the [player.HealthChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/HealthChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.healthChange = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.HealthChangeHook,callback,priority); +}; +/********************* +### events.disconnection() + +#### Parameters + + * callback - A function which is called whenever the [player.DisconnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/DisconnectionHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.disconnection = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.DisconnectionHook,callback,priority); +}; +/********************* +### events.gameModeChange() + +#### Parameters + + * callback - A function which is called whenever the [player.GameModeChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/GameModeChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.gameModeChange = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.GameModeChangeHook,callback,priority); +}; +/********************* +### events.preConnection() + +#### Parameters + + * callback - A function which is called whenever the [player.PreConnectionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PreConnectionHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.preConnection = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PreConnectionHook,callback,priority); +}; +/********************* +### events.villagerTrade() + +#### Parameters + + * callback - A function which is called whenever the [player.VillagerTradeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/VillagerTradeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.villagerTrade = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.VillagerTradeHook,callback,priority); +}; +/********************* +### events.returnFromIdle() + +#### Parameters + + * callback - A function which is called whenever the [player.ReturnFromIdleHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ReturnFromIdleHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.returnFromIdle = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ReturnFromIdleHook,callback,priority); +}; +/********************* +### events.armorStandModify() + +#### Parameters + + * callback - A function which is called whenever the [player.ArmorStandModifyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ArmorStandModifyHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.armorStandModify = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ArmorStandModifyHook,callback,priority); +}; +/********************* +### events.slotClick() + +#### Parameters + + * callback - A function which is called whenever the [player.SlotClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SlotClickHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.slotClick = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.SlotClickHook,callback,priority); +}; +/********************* +### events.itemFrameSetItem() + +#### Parameters + + * callback - A function which is called whenever the [player.ItemFrameSetItemHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemFrameSetItemHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.itemFrameSetItem = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ItemFrameSetItemHook,callback,priority); +}; +/********************* +### events.entityRightClick() + +#### Parameters + + * callback - A function which is called whenever the [player.EntityRightClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/EntityRightClickHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.entityRightClick = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.EntityRightClickHook,callback,priority); +}; +/********************* +### events.foodExhaustion() + +#### Parameters + + * callback - A function which is called whenever the [player.FoodExhaustionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/FoodExhaustionHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.foodExhaustion = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.FoodExhaustionHook,callback,priority); +}; +/********************* +### events.chat() + +#### Parameters + + * callback - A function which is called whenever the [player.ChatHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ChatHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chat = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ChatHook,callback,priority); +}; +/********************* +### events.itemPickup() + +#### Parameters + + * callback - A function which is called whenever the [player.ItemPickupHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemPickupHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.itemPickup = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ItemPickupHook,callback,priority); +}; +/********************* +### events.bedExit() + +#### Parameters + + * callback - A function which is called whenever the [player.BedExitHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BedExitHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.bedExit = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.BedExitHook,callback,priority); +}; +/********************* +### events.blockPlace() + +#### Parameters + + * callback - A function which is called whenever the [player.BlockPlaceHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockPlaceHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockPlace = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.BlockPlaceHook,callback,priority); +}; +/********************* +### events.heldItemChange() + +#### Parameters + + * callback - A function which is called whenever the [player.HeldItemChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/HeldItemChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.heldItemChange = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.HeldItemChangeHook,callback,priority); +}; +/********************* +### events.toolBroken() + +#### Parameters + + * callback - A function which is called whenever the [player.ToolBrokenHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ToolBrokenHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.toolBroken = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ToolBrokenHook,callback,priority); +}; +/********************* +### events.kick() + +#### Parameters + + * callback - A function which is called whenever the [player.KickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/KickHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.kick = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.KickHook,callback,priority); +}; +/********************* +### events.playerDeath() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerDeathHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerDeathHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerDeath = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PlayerDeathHook,callback,priority); +}; +/********************* +### events.blockLeftClick() + +#### Parameters + + * callback - A function which is called whenever the [player.BlockLeftClickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockLeftClickHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockLeftClick = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.BlockLeftClickHook,callback,priority); +}; +/********************* +### events.blockDestroy() + +#### Parameters + + * callback - A function which is called whenever the [player.BlockDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BlockDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockDestroy = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.BlockDestroyHook,callback,priority); +}; +/********************* +### events.bedEnter() + +#### Parameters + + * callback - A function which is called whenever the [player.BedEnterHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BedEnterHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.bedEnter = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.BedEnterHook,callback,priority); +}; +/********************* +### events.signShow() + +#### Parameters + + * callback - A function which is called whenever the [player.SignShowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/SignShowHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.signShow = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.SignShowHook,callback,priority); +}; +/********************* +### events.inventory() + +#### Parameters + + * callback - A function which is called whenever the [player.InventoryHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/InventoryHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.inventory = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.InventoryHook,callback,priority); +}; +/********************* +### events.playerMove() + +#### Parameters + + * callback - A function which is called whenever the [player.PlayerMoveHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/PlayerMoveHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerMove = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.PlayerMoveHook,callback,priority); +}; +/********************* +### events.itemUse() + +#### Parameters + + * callback - A function which is called whenever the [player.ItemUseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/ItemUseHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.itemUse = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.ItemUseHook,callback,priority); +}; +/********************* +### events.ban() + +#### Parameters + + * callback - A function which is called whenever the [player.BanHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/BanHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.ban = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.BanHook,callback,priority); +}; +/********************* +### events.statGained() + +#### Parameters + + * callback - A function which is called whenever the [player.StatGainedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/player/StatGainedHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.statGained = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.player.StatGainedHook,callback,priority); +}; +/********************* +### events.smeltBegin() + +#### Parameters + + * callback - A function which is called whenever the [world.SmeltBeginHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/SmeltBeginHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.smeltBegin = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.SmeltBeginHook,callback,priority); +}; +/********************* +### events.treeGrow() + +#### Parameters + + * callback - A function which is called whenever the [world.TreeGrowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TreeGrowHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.treeGrow = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.TreeGrowHook,callback,priority); +}; +/********************* +### events.chunkCreated() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkCreatedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkCreatedHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chunkCreated = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.ChunkCreatedHook,callback,priority); +}; +/********************* +### events.liquidDestroy() + +#### Parameters + + * callback - A function which is called whenever the [world.LiquidDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LiquidDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.liquidDestroy = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.LiquidDestroyHook,callback,priority); +}; +/********************* +### events.chunkLoaded() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkLoadedHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkLoadedHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chunkLoaded = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.ChunkLoadedHook,callback,priority); +}; +/********************* +### events.pistonRetract() + +#### Parameters + + * callback - A function which is called whenever the [world.PistonRetractHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PistonRetractHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.pistonRetract = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.PistonRetractHook,callback,priority); +}; +/********************* +### events.smelt() + +#### Parameters + + * callback - A function which is called whenever the [world.SmeltHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/SmeltHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.smelt = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.SmeltHook,callback,priority); +}; +/********************* +### events.blockUpdate() + +#### Parameters + + * callback - A function which is called whenever the [world.BlockUpdateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockUpdateHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockUpdate = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.BlockUpdateHook,callback,priority); +}; +/********************* +### events.portalDestroy() + +#### Parameters + + * callback - A function which is called whenever the [world.PortalDestroyHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PortalDestroyHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.portalDestroy = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.PortalDestroyHook,callback,priority); +}; +/********************* +### events.ignition() + +#### Parameters + + * callback - A function which is called whenever the [world.IgnitionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/IgnitionHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.ignition = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.IgnitionHook,callback,priority); +}; +/********************* +### events.redstoneChange() + +#### Parameters + + * callback - A function which is called whenever the [world.RedstoneChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/RedstoneChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.redstoneChange = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.RedstoneChangeHook,callback,priority); +}; +/********************* +### events.weatherChange() + +#### Parameters + + * callback - A function which is called whenever the [world.WeatherChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/WeatherChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.weatherChange = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.WeatherChangeHook,callback,priority); +}; +/********************* +### events.chunkCreation() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkCreationHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkCreationHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chunkCreation = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.ChunkCreationHook,callback,priority); +}; +/********************* +### events.hopperTransfer() + +#### Parameters + + * callback - A function which is called whenever the [world.HopperTransferHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/HopperTransferHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.hopperTransfer = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.HopperTransferHook,callback,priority); +}; +/********************* +### events.chunkUnload() + +#### Parameters + + * callback - A function which is called whenever the [world.ChunkUnloadHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ChunkUnloadHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.chunkUnload = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.ChunkUnloadHook,callback,priority); +}; +/********************* +### events.blockGrow() + +#### Parameters + + * callback - A function which is called whenever the [world.BlockGrowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockGrowHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockGrow = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.BlockGrowHook,callback,priority); +}; +/********************* +### events.dispense() + +#### Parameters + + * callback - A function which is called whenever the [world.DispenseHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/DispenseHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.dispense = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.DispenseHook,callback,priority); +}; +/********************* +### events.blockDropXp() + +#### Parameters + + * callback - A function which is called whenever the [world.BlockDropXpHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockDropXpHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockDropXp = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.BlockDropXpHook,callback,priority); +}; +/********************* +### events.fireworkExplode() + +#### Parameters + + * callback - A function which is called whenever the [world.FireworkExplodeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/FireworkExplodeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.fireworkExplode = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.FireworkExplodeHook,callback,priority); +}; +/********************* +### events.leafDecay() + +#### Parameters + + * callback - A function which is called whenever the [world.LeafDecayHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LeafDecayHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.leafDecay = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.LeafDecayHook,callback,priority); +}; +/********************* +### events.pistonExtend() + +#### Parameters + + * callback - A function which is called whenever the [world.PistonExtendHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PistonExtendHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.pistonExtend = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.PistonExtendHook,callback,priority); +}; +/********************* +### events.noteBlockPlay() + +#### Parameters + + * callback - A function which is called whenever the [world.NoteBlockPlayHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/NoteBlockPlayHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.noteBlockPlay = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.NoteBlockPlayHook,callback,priority); +}; +/********************* +### events.lightningStrike() + +#### Parameters + + * callback - A function which is called whenever the [world.LightningStrikeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/LightningStrikeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.lightningStrike = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.LightningStrikeHook,callback,priority); +}; +/********************* +### events.decorate() + +#### Parameters + + * callback - A function which is called whenever the [world.DecorateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/DecorateHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.decorate = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.DecorateHook,callback,priority); +}; +/********************* +### events.explosion() + +#### Parameters + + * callback - A function which is called whenever the [world.ExplosionHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/ExplosionHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.explosion = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.ExplosionHook,callback,priority); +}; +/********************* +### events.tNTActivate() + +#### Parameters + + * callback - A function which is called whenever the [world.TNTActivateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TNTActivateHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.tNTActivate = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.TNTActivateHook,callback,priority); +}; +/********************* +### events.timeChange() + +#### Parameters + + * callback - A function which is called whenever the [world.TimeChangeHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/TimeChangeHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.timeChange = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.TimeChangeHook,callback,priority); +}; +/********************* +### events.flow() + +#### Parameters + + * callback - A function which is called whenever the [world.FlowHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/FlowHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.flow = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.FlowHook,callback,priority); +}; +/********************* +### events.portalCreate() + +#### Parameters + + * callback - A function which is called whenever the [world.PortalCreateHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/PortalCreateHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.portalCreate = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.PortalCreateHook,callback,priority); +}; +/********************* +### events.blockPhysics() + +#### Parameters + + * callback - A function which is called whenever the [world.BlockPhysicsHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/world/BlockPhysicsHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.blockPhysics = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.world.BlockPhysicsHook,callback,priority); +}; +/********************* +### events.playerCommand() + +#### Parameters + + * callback - A function which is called whenever the [command.PlayerCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/PlayerCommandHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.playerCommand = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.command.PlayerCommandHook,callback,priority); +}; +/********************* +### events.consoleCommand() + +#### Parameters + + * callback - A function which is called whenever the [command.ConsoleCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/ConsoleCommandHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.consoleCommand = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.command.ConsoleCommandHook,callback,priority); +}; +/********************* +### events.commandBlockCommand() + +#### Parameters + + * callback - A function which is called whenever the [command.CommandBlockCommandHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/command/CommandBlockCommandHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.commandBlockCommand = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.command.CommandBlockCommandHook,callback,priority); +}; +/********************* +### events.loadWorld() + +#### Parameters + + * callback - A function which is called whenever the [system.LoadWorldHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/LoadWorldHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.loadWorld = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.LoadWorldHook,callback,priority); +}; +/********************* +### events.permissionCheck() + +#### Parameters + + * callback - A function which is called whenever the [system.PermissionCheckHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PermissionCheckHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.permissionCheck = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.PermissionCheckHook,callback,priority); +}; +/********************* +### events.serverGuiStart() + +#### Parameters + + * callback - A function which is called whenever the [system.ServerGuiStartHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerGuiStartHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.serverGuiStart = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.ServerGuiStartHook,callback,priority); +}; +/********************* +### events.unloadWorld() + +#### Parameters + + * callback - A function which is called whenever the [system.UnloadWorldHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/UnloadWorldHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.unloadWorld = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.UnloadWorldHook,callback,priority); +}; +/********************* +### events.pluginDisable() + +#### Parameters + + * callback - A function which is called whenever the [system.PluginDisableHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PluginDisableHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.pluginDisable = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.PluginDisableHook,callback,priority); +}; +/********************* +### events.pluginEnable() + +#### Parameters + + * callback - A function which is called whenever the [system.PluginEnableHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/PluginEnableHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.pluginEnable = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.PluginEnableHook,callback,priority); +}; +/********************* +### events.serverTick() + +#### Parameters + + * callback - A function which is called whenever the [system.ServerTickHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerTickHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.serverTick = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.ServerTickHook,callback,priority); +}; +/********************* +### events.serverListPing() + +#### Parameters + + * callback - A function which is called whenever the [system.ServerListPingHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerListPingHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.serverListPing = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.ServerListPingHook,callback,priority); +}; +/********************* +### events.serverShutdown() + +#### Parameters + + * callback - A function which is called whenever the [system.ServerShutdownHook event](https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/system/ServerShutdownHook.html) is fired + + * priority - optional - see events.on() for more information. + +***/ +exports.serverShutdown = function(callback,priority){ + return events.on(Packages.net.canarymod.hook.system.ServerShutdownHook,callback,priority); +}; diff --git a/server/scriptcraft/lib/events.js b/server/scriptcraft/lib/events.js new file mode 100755 index 0000000..f66fd11 --- /dev/null +++ b/server/scriptcraft/lib/events.js @@ -0,0 +1,112 @@ +'use strict'; +/************************************************************************ +## events Module + +The Events module provides a thin wrapper around CanaryMod's or +Bukkit's Event-handling API. The Java-based CanaryMod and Bukkit +Events APIs make use of Java Annotations which are not available in +Javascript, so this module provides a simple way to listen to +minecraft events in javascript. + +### events.on() static method + +This method is used to register event listeners. This method is called by all of the Event Helper methods. +The `events` object has functions for registering listeners for each type of event. For example, you can register a block-break listener using events.on: + +```javascript +events.on( Packages.net.canarymod.hook.player.BlockDestroyHook, function( evt, cancel ) { + echo(evt.player, evt.player.name + ' broke a block!'); +} ); +``` + +or you can (and probably should) use the more succinct: + +```javascript +events.blockDestroy( function( evt, cancel ) { + echo(evt.player, evt.player.name + ' broke a block!'); +} ); +``` + +The events.on method can be used to register standard CanaryMod/Bukkit +events and can also be used to register non-standard events - that is +- events provided by plugins. + +#### Parameters + + * eventType - A Java class. See the [CanaryMod Hook API][cmEvtApi] or [Bukkit Event API][buk] for details of the many event types. + + * callback - A function which will be called whenever the event + fires. The callback in turn takes 2 parameters: + + - event : the event fired + - cancel : a function which if invoked will cancel the event - not all event types are cancelable; this function only cancels cancelable events). + + * priority (optional - default: "CRITICAL" for CanaryMod or "HIGHEST" for Bukkit) - + The priority the listener/callback takes over other listeners to the same event. + Possible values for CanaryMod are "CRITICAL", "HIGH", "LOW", "NORMAL" and "PASSIVE". + For an explanation of what the different CanaryMod Hook priorities + mean, refer to CanaryMod's [Hook Priority class][cmPriority]. + Possible values for Bukkit are "HIGH", "HIGHEST", "LOW", "LOWEST", "NORMAL", "MONITOR". + For an explanation of what the different Bukkit Event priorities + mean, refer to bukkit's [Event API Reference][buk2]. + +#### Returns + +An object which can be used to unregister the listener. + +#### Example: + +The following code will print a message on screen every time a block is broken in the game + +```javascript +events.on( Packages.net.canarymod.hook.player.BlockDestroyHook, function( evt, cancel ) { + echo(evt.player, evt.player.name + ' broke a block!'); +} ); +``` + +To handle an event only once and unregister from further events... + +```javascript +events.on( Packages.net.canarymod.hook.player.BlockDestroyHook, function( evt, cancel ) { + echo( evt.player, evt.player.name + ' broke a block!'); + this.unregister(); +} ); +``` + +The `this` keyword when used inside the callback function refers to +the Listener object created by ScriptCraft. It has 2 methods +`unregister()` which can be used to stop listening and `cancel()` +which can be used to cancel the current event. The object returned by +`events.on()` only has the `unregister()` method, the `cancel()` +method is only available from within the event handling function. + +To unregister a listener *outside* of the listener function... + +```javascript +var myBlockBreakListener = events.on( Packages.net.canarymod.hook.player.BlockDestroyHook, function( evt ) { ... } ); +... +myBlockBreakListener.unregister(); +``` + +[buk2]: http://wiki.bukkit.org/Event_API_Reference +[buk]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/event/Event.html +[cmEvtApi]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/hook/Hook.html +[cmPriority]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/plugin/Priority.html + +***/ +var helper; +/*global __plugin, module, require*/ +if (__plugin.canary){ + module.exports = require('events-canary'); + helper = require('events-helper-canary'); + // backwards-compatibility with canarymod 1.7.9 for book listings + if (helper.connection && !helper.connect){ + helper.connect = helper.connection; + } +} else { + module.exports = require('events-bukkit'); + helper = require('events-helper-bukkit'); +} +for ( var func in helper ) { + module.exports[func] = helper[func]; +}; diff --git a/server/scriptcraft/lib/find.js b/server/scriptcraft/lib/find.js new file mode 100755 index 0000000..2f686ff --- /dev/null +++ b/server/scriptcraft/lib/find.js @@ -0,0 +1,29 @@ +'use strict'; +var File = java.io.File; +module.exports = function find(dir, filter) { + var result = []; + function recurse( dir, store ) { + var files, + len, + i, + file, + dirfile = new File( dir ); + + if ( typeof filter == 'undefined' ) { + files = dirfile.list(); + } else { + files = dirfile.list(filter); + } + len = files.length; i = 0; + for (; i < len; i++){ + file = new File( dir + '/' + files[i] ); + if ( file.isDirectory() ) { + recurse( file.canonicalPath, store ); + } else { + store.push( ('' + file.canonicalPath).replace(/\\\\/g,'/') ); + } + } + } + recurse( dir, result ); + return result; +}; diff --git a/server/scriptcraft/lib/java-utils.js b/server/scriptcraft/lib/java-utils.js new file mode 100755 index 0000000..aaa065e --- /dev/null +++ b/server/scriptcraft/lib/java-utils.js @@ -0,0 +1,29 @@ +exports.isJavaObject = function( o ) { + if (o === global){ + return false; + } + if (o !== undefined && o !== null){ + try { + // this throws error for java objects in jre7 + if (typeof o.constructor === 'function'){ + return false; + } + } catch (e){ + return true; + } + try { + var result = o.getClass ? true : false; // throws error for Enums/Class in jre7 + if (result == true){ + return result; + } + }catch (e2){ + // fail silently and move on to next test + } + // java classes don't have a getClass so just because .getClass isn't present + // doesn't mean it's not a Java Enum or Class (.getClass only works for object instances?) + if (o instanceof java.lang.Object){ + return true; + } + } + return o instanceof java.lang.Object; +}; diff --git a/server/scriptcraft/lib/js-patch.js b/server/scriptcraft/lib/js-patch.js new file mode 100755 index 0000000..20cd7fa --- /dev/null +++ b/server/scriptcraft/lib/js-patch.js @@ -0,0 +1,77 @@ +module.exports = function( $ ) { + + // wph 20140105 trim not availabe in String on Mac OS. + if ( typeof String.prototype.trim == 'undefined' ) { + String.prototype.trim = function( ) { + return this.replace( /^\s+|\s+$/g, '' ); + }; + } + + // wph 20140316 Java 1.6.0_65 on mac does not have Function.prototype.bind + // code from http://webreflection.blogspot.ie/2010/02/functionprototypebind.html + if (typeof Function.prototype.bind == 'undefined' ) { + Function.prototype.bind = (function (slice){ + // (C) WebReflection - Mit Style License + function bind(context) { + var self = this; // "trapped" function reference + // only if there is more than an argument + // we are interested into more complex operations + // this will speed up common bind creation + // avoiding useless slices over arguments + if (1 < arguments.length) { + // extra arguments to send by default + var $arguments = slice.call(arguments, 1); + return function () { + return self.apply( + context, + // thanks @kangax for this suggestion + arguments.length ? + // concat arguments with those received + $arguments.concat(slice.call(arguments)) : + // send just arguments, no concat, no slice + $arguments + ); + }; + } + // optimized callback + return function () { + // speed up when function is called without arguments + return arguments.length ? self.apply(context, arguments) : self.call(context); + }; + } + // the named function + return bind; + }(Array.prototype.slice)); + } + + if (__plugin.canary){ + require('task-canary')($); + } else { + require('task-bukkit')($); + } + + return function unitTest( console ) { + /* + sanity tests + */ + $.setTimeout(function(){ + console.log('js-patch setTimeout() test complete'); + },100); + var clearMe = $.setTimeout(function(){ + console.error('js-patch clearTimeout() test failed'); + },100); + $.clearTimeout( clearMe ); + + var runs = 3; + var clearAfterRuns = $.setInterval(function(){ + runs --; + if (runs == 0){ + $.clearInterval(clearAfterRuns); + } + if (runs < 0){ + console.error('js-patch clearInterval test failed.'); + } + },100); + }; +}; + diff --git a/server/scriptcraft/lib/json2.js b/server/scriptcraft/lib/json2.js new file mode 100755 index 0000000..d89ecc7 --- /dev/null +++ b/server/scriptcraft/lib/json2.js @@ -0,0 +1,486 @@ +/* + json2.js + 2013-05-26 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function () { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function () { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); diff --git a/server/scriptcraft/lib/legacy-check.js b/server/scriptcraft/lib/legacy-check.js new file mode 100755 index 0000000..b13da08 --- /dev/null +++ b/server/scriptcraft/lib/legacy-check.js @@ -0,0 +1,33 @@ +var File = java.io.File; +/* + wph 20140102 - warn if legacy 'mcserver/js-plugins' or + 'mcserver/plugins/scriptcraft' directories are present + */ +module.exports = function( jsPluginsRootDir ) { + var mcServerDir = new File(jsPluginsRootDir.canonicalPath).parentFile; + if (mcServerDir == null){ + console.warn('Could not find parent directory for ' + jsPluginsRootDir.canonicalPath); + return; + } + var legacyExists = false, + legacyDirs = [ + new File( mcServerDir, 'js-plugins' ), + new File( mcServerDir, 'plugins/scriptcraft' ) + ]; + + for ( var i = 0; i < legacyDirs.length; i++ ) { + if ( legacyDirs[i].exists() + && legacyDirs[i].isDirectory() ) { + + legacyExists = true; + + console.warn('Legacy ScriptCraft directory %s was found. This directory is no longer used.', + legacyDirs[i].canonicalPath); + console.warn('Please put plugins in the ' + jsPluginsRootDir.canonicalPath + '/plugins directory'); + } + } + if ( legacyExists ) { + console.info( 'Please note that the working directory for %s is %s', + __plugin, jsPluginsRootDir.canonicalPath ); + } +}; diff --git a/server/scriptcraft/lib/nashorn-type.js b/server/scriptcraft/lib/nashorn-type.js new file mode 100755 index 0000000..ad3f731 --- /dev/null +++ b/server/scriptcraft/lib/nashorn-type.js @@ -0,0 +1,8 @@ +/* + The .class operator causes problems for non-nashorn Java on Mac OS X and some other + environments. So need to have it in a separate module which should only be loaded in + nashorn environment. +*/ +module.exports = function(t){ + return t.class; +}; diff --git a/server/scriptcraft/lib/persistence.js b/server/scriptcraft/lib/persistence.js new file mode 100755 index 0000000..36eabb4 --- /dev/null +++ b/server/scriptcraft/lib/persistence.js @@ -0,0 +1,52 @@ +var _dataDir = null, + _persistentData = {}; + +module.exports = function( rootDir, $ ) { + + var _load = function( name ) { + var result = $.scloadJSON( _dataDir.canonicalPath + '/' + name + '-store.json' ); + return result; + }; + + var _save = function( name, objToSave ) { + $.scsave( objToSave, _dataDir.canonicalPath + '/' + name + '-store.json' ); + }; + + _dataDir = new java.io.File( rootDir, 'data' ); + + $.persist = function( name, data, write ) { + var i, + dataFromFile; + if ( typeof data == 'undefined' ) { + data = {}; + } + if ( typeof write == 'undefined' ) { + write = false; + } + if ( !write ) { + dataFromFile = _load( name ); + if ( typeof dataFromFile != 'undefined') { + for ( i in dataFromFile ) { + data[i] = dataFromFile[i]; + } + } + } else { + // flush data to file + _save( name, data ); + } + _persistentData[name] = data; + return data; + }; + /* + persist on shutdown + */ + $.addUnloadHandler( function( ) { + var name, + data; + for ( name in _persistentData ) { + data = _persistentData[name]; + _save( name, data ); + } + }); +}; + diff --git a/server/scriptcraft/lib/plugin.js b/server/scriptcraft/lib/plugin.js new file mode 100755 index 0000000..ac64be9 --- /dev/null +++ b/server/scriptcraft/lib/plugin.js @@ -0,0 +1,72 @@ +'use strict'; +/*global persist,exports,config,__plugin,require*/ +var File = java.io.File, + FileWriter = java.io.FileWriter, + PrintWriter = java.io.PrintWriter, + find = require('./find'); +/* + plugin management +*/ +var _plugins = {}; + +function _plugin(/* String */ moduleName, /* Object */ moduleObject, isPersistent ) { + // + // don't load plugin more than once + // + if ( typeof _plugins[moduleName] != 'undefined' ) { + return _plugins[moduleName].module; + } + + var pluginData = { persistent: isPersistent, module: moduleObject }; + if ( typeof moduleObject.store == 'undefined' ) { + moduleObject.store = {}; + } + _plugins[moduleName] = pluginData; + + if ( isPersistent ) { + moduleObject.store = persist( moduleName, moduleObject.store ); + } + return moduleObject; +} + +function _autoload( context, pluginDir, options ) { + /* + Reload all of the .js files in the given directory + */ + var sourceFiles = [], + property, + module, + pluginPath; + sourceFiles = find(pluginDir); + + var len = sourceFiles.length; + if ( config && config.verbose ) { + console.info( len + ' scriptcraft plugins found in ' + pluginDir ); + } + + for ( var i = 0; i < len; i++ ) { + + pluginPath = sourceFiles[i]; + if (!pluginPath.match(/\.js$/)){ + continue; + } + module = {}; + + try { + module = require( pluginPath , options); + for ( property in module ) { + /* + all exports in plugins become members of context object + */ + context[property] = module[property]; + } + } catch ( e ) { + var msg = 'Plugin ' + pluginPath + ' ' + e ; + console.error( msg ); + } + } + +} +exports.plugin = _plugin; +exports.autoload = _autoload; + diff --git a/server/scriptcraft/lib/readme.md b/server/scriptcraft/lib/readme.md new file mode 100755 index 0000000..972a966 --- /dev/null +++ b/server/scriptcraft/lib/readme.md @@ -0,0 +1,12 @@ +# lib directory + +This directory contains core scriptcraft files and modules. + + * plugin.js - A module which provides support for persistent plugins (plugins which need to save state) + * require.js - The require() function implementation. See [Node.js modules] documentation. + * scriptcraft.js - The core scriptcraft code. + * events.js - Event handling module for use by plugin/module developers. + +When `require('modulename')` is called, if a file in the current working directory called 'modulename' is not found then the `lib` folder is the first location that `require()` looks for modules. + +[njsmod]: http://nodejs.org/api/modules.html diff --git a/server/scriptcraft/lib/require.js b/server/scriptcraft/lib/require.js new file mode 100755 index 0000000..4090e1d --- /dev/null +++ b/server/scriptcraft/lib/require.js @@ -0,0 +1,322 @@ +/************************************************************************* +## require - Node.js-style module loading in ScriptCraft + +Node.js is a server-side javascript environment with an excellent +module loading system based on CommonJS. Modules in Node.js are really +simple. Each module is in its own javascript file and all variables +and functions within the file are private to that file/module only. +There is a very concise explanation of CommonJS modules at... + +[http://wiki.commonjs.org/wiki/Modules/1.1.1.][cjsmodules] + +Node.js also has good documentation on [Modules][njsmod]. + +If you want to export a variable or function you use the module.export +property. + +For example imagine you have 3 files program.js, inc.js and math.js ... + +### math.js + +```javascript +exports.add = function(a,b){ + return a + b; +} +``` + +### inc.js + +```javascript +var math = require('./math'); +exports.increment = function(n){ + return math.add(n, 1); +} +``` + +### program.js + +```javascript +var inc = require('./inc').increment; +var a = 7; +a = inc(a); +print(a); +``` + +You can see from the above sample code that programs can use modules +and modules themeselves can use other modules. Modules have full +control over what functions and properties they want to provide to +others. + +### Important + +Although ScriptCraft now supports Node.js style modules, it does not +support node modules. Node.js and Rhino are two very different +Javascript environments. ScriptCraft uses Rhino Javascript, not +Node.js. Standard Node.js modules such as `'fs'` are not available in ScriptCraft. + +Modules can be loaded using relative or absolute paths. Per the CommonJS +module specification, the '.js' suffix is optional. + +[cjsmodules]: http://wiki.commonjs.org/wiki/Modules/1.1.1. + +***/ +(function ( rootDir, modulePaths, hooks, evaluate ) { + + var File = java.io.File, + FileReader = java.io.FileReader, + BufferedReader = java.io.BufferedReader; + + function fileExists( file ) { + if ( file.isDirectory() ) { + return readModuleFromDirectory( file ); + } else { + return file; + } + } + + function _canonize(file){ + return "" + file.canonicalPath.replaceAll("\\\\","/"); + } + + function readModuleFromDirectory( dir ) { + + // look for a package.json file + var pkgJsonFile = new File( dir, './package.json' ); + if ( pkgJsonFile.exists() ) { + var pkg = scload( pkgJsonFile ); + var mainFile = new File( dir, pkg.main ); + if ( mainFile.exists() ) { + return mainFile; + } else { + return null; + } + } else { + // look for an index.js file + var indexJsFile = new File( dir, './index.js' ); + if ( indexJsFile.exists() ) { + return indexJsFile; + } else { + return null; + } + } + } + + +/********************************************************************** +### module name resolution + +When resolving module names to file paths, ScriptCraft uses the following rules... + + 1. if the module does not begin with './' or '/' then ... + + 1.1 Look in the 'scriptcraft/lib' directory. If it's not there then... + 1.2 Look in the 'scriptcraft/modules' directory. If it's not there then + Throw an Error. + + 2. If the module begins with './' or '/' then ... + + 2.1 if the module begins with './' then it's treated as a file path. File paths are + always relative to the module from which the require() call is being made. + + 2.2 If the module begins with '/' then it's treated as an absolute path. + + If the module does not have a '.js' suffix, and a file with the same name and a .js sufix exists, + then the file will be loaded. + + 3. If the module name resolves to a directory then... + + 3.1 look for a package.json file in the directory and load the `main` property e.g. + + // package.json located in './some-library/' + { + "main": './some-lib.js', + "name": 'some-library' + } + + 3.2 if no package.json file exists then look for an index.js file in the directory + +***/ + function resolveModuleToFile( moduleName, parentDir ) { + var file = new File(moduleName), + i = 0, + pathWithJSExt, + resolvedFile; + if ( file.exists() ) { + return fileExists(file); + } + if ( moduleName.match( /^[^\.\/]/ ) ) { + // it's a module named like so ... 'events' , 'net/http' + // + for ( ; i < modulePaths.length; i++ ) { + resolvedFile = new File(modulePaths[i] + moduleName); + if ( resolvedFile.exists() ) { + return fileExists(resolvedFile); + } else { + // try appending a .js to the end + resolvedFile = new File(modulePaths[i] + moduleName + '.js'); + if ( resolvedFile.exists() ) { + return resolvedFile; + } + } + } + } else { + // it's of the form ./path + file = new File(parentDir, moduleName); + if ( file.exists() ) { + return fileExists(file); + } else { + // try appending a .js to the end + pathWithJSExt = file.canonicalPath + '.js'; + file = new File( parentDir, pathWithJSExt ); + if (file.exists()) { + return file; + } else { + file = new File(pathWithJSExt); + if ( file.exists() ) { + return file; + } + } + + } + } + return null; + } + /* + require() function implementation + */ + function _require( parentFile, path, options ) { + var file, + canonizedFilename, + moduleInfo, + buffered, + head = '(function(exports,module,require,__filename,__dirname){ ', + code = '', + line = null; + + if ( typeof options == 'undefined' ) { + options = { cache: true }; + } else { + if ( typeof options.cache == 'undefined' ) { + options.cache = true; + } + } + + file = resolveModuleToFile(path, parentFile); + if ( !file ) { + var errMsg = '' + _format("require() failed to find matching file for module '%s' " + + "in working directory '%s' ", [path, parentFile.canonicalPath]); + if (! ( (''+path).match( /^\./ ) ) ) { + errMsg = errMsg + ' and not found in paths ' + JSON.stringify(modulePaths); + } + var find = _require(parentFile, 'find').exports; + var allJS = []; + for (var i = 0;i < modulePaths.length; i++){ + var js = find( modulePaths[i] ); + for (var j = 0;j < js.length; j++){ + if (js[j].match(/\.js$/)){ + allJS.push( js[j].replace(modulePaths[i],'') ); + } + } + } + var pathL = path.toLowerCase(); + var candidates = []; + for (i = 0;i < allJS.length;i++){ + var filenameparts = allJS[i]; + var candidate = filenameparts.replace(/\.js/,'') ; + var lastpart = candidate.toLowerCase(); + if (pathL.indexOf(lastpart) > -1 || lastpart.indexOf(pathL) > -1){ + candidates.push(candidate); + } + } + if (candidates.length > 0){ + errMsg += '\nBut found module/s named: ' + candidates.join(',') + ' - is this what you meant?'; + } + throw new Error(errMsg); + } + canonizedFilename = _canonize(file); + + moduleInfo = _loadedModules[canonizedFilename]; + if ( moduleInfo ) { + if ( options.cache ) { + return moduleInfo; + } + } + if ( hooks ) { + hooks.loading( canonizedFilename ); + } + buffered = new BufferedReader(new FileReader(file)); + while ( (line = buffered.readLine()) !== null ) { + code += line + '\n'; + } + buffered.close(); // close the stream so there's no file locks + + moduleInfo = { + loaded: false, + id: canonizedFilename, + exports: {}, + require: _requireClosure(file.parentFile) + }; + var tail = '})'; + code = head + code + tail; + + if ( options.cache ) { + _loadedModules[canonizedFilename] = moduleInfo; + } + var compiledWrapper = null; + try { + compiledWrapper = evaluate(code); + } catch (e) { + /* + wph 20140313 JRE8 (nashorn) gives misleading linenumber of evaluating code not evaluated code. + This can be fixed by instead using __engine.eval + */ + throw new Error( "Error evaluating module " + path + + " line #" + e.lineNumber + + " : " + e.message, canonizedFilename, e.lineNumber ); + } + var __dirname = '' + file.parentFile.canonicalPath; + var parameters = [ + moduleInfo.exports, /* exports */ + moduleInfo, /* module */ + moduleInfo.require, /* require */ + canonizedFilename, /* __filename */ + __dirname /* __dirname */ + ]; + try { + compiledWrapper + .apply(moduleInfo.exports, /* this */ + parameters); + } catch (e) { + var snippet = ''; + if ((''+e.lineNumber).match(/[0-9]/)){ + var lines = code.split(/\n/); + if (e.lineNumber > 1){ + snippet = ' ' + lines[e.lineNumber-2] + '\n'; + } + snippet += '> ' + lines[e.lineNumber-1] + '\n'; + if (e.lineNumber < lines.length){ + snippet += ' ' + lines[e.lineNumber] + '\n'; + } + } + throw new Error( "Error executing module " + path + + " line #" + e.lineNumber + + " : " + e.message + (snippet?('\n' + snippet):''), canonizedFilename, e.lineNumber ); + } + if ( hooks ) { + hooks.loaded( canonizedFilename ); + } + moduleInfo.loaded = true; + return moduleInfo; + } + + function _requireClosure( parent ) { + return function requireBoundToParent( path, options ) { + var module = _require( parent, path , options); + return module.exports; + }; + } + var _loadedModules = {}; + var _format = java.lang.String.format; + return _requireClosure( new java.io.File(rootDir) ); + // last line deliberately has no semicolon! +}) diff --git a/server/scriptcraft/lib/scriptcraft.js b/server/scriptcraft/lib/scriptcraft.js new file mode 100755 index 0000000..0f7428d --- /dev/null +++ b/server/scriptcraft/lib/scriptcraft.js @@ -0,0 +1,777 @@ +'use strict'; +/*global require*/ +/************************************************************************ + +## Modules in Scriptcraft + +ScriptCraft has a simple module loading system. In ScriptCraft, files +and modules are in one-to-one correspondence. As an example, foo.js +loads the module circle.js in the same directory. +*ScriptCraft now uses the same module system as Node.js - see [Node.js Modules][njsmod] for more details.* + +[njsmod]: http://nodejs.org/api/modules.html + +The contents of foo.js: + +```javascript +var circle = require('./circle.js'); +console.log( 'The area of a circle of radius 4 is ' + + circle.area(4)); +``` + +The contents of circle.js: + +```javascript +var PI = Math.PI; +exports.area = function (r) { + return PI * r * r; +}; +exports.circumference = function (r) { + return 2 * PI * r; +}; +``` + +The module circle.js has exported the functions area() and +circumference(). To add functions and objects to the root of your +module, you can add them to the special exports object. + +Variables local to the module will be private, as though the module +was wrapped in a function. In this example the variable PI is private +to circle.js. + +If you want the root of your module's export to be a function (such as +a constructor) or if you want to export a complete object in one +assignment instead of building it one property at a time, assign it to +module.exports instead of exports. + +## Module Loading + +When the ScriptCraft Java plugin is first installed, a new +`scriptcraft` subdirectory is created. If your minecraft server +directory is called 'mcserver' then the new subdirectories will be ... + + * mcserver/scriptcraft/ + * mcserver/scriptcraft/plugins + * mcserver/scriptcraft/modules + * mcserver/scriptcraft/lib + +... The `plugins`, `modules` and `lib` directories each serve a different purpose. + +### The plugins directory + +At server startup the ScriptCraft Java plugin is loaded and begins +automatically loading and executing all of the modules (javascript +files with the extension `.js`) it finds in the `scriptcraft/plugins` +directory. All modules in the plugins directory are automatically +loaded into the `global` namespace. What this means is that anything a +module in the `plugins` directory exports becomes a global +variable. For example, if you have a module greeting.js in the plugins +directory.... + +```javascript +exports.greet = function(player) { + echo(player, 'Hello ' + player.name); +}; +``` + +... then `greet` becomes a global function and can be used at the +in-game (or server) command prompt like so... + + /js greet(self) + +... This differs from how modules (in NodeJS and commonJS +environments) normally work. If you want your module to be exported +globally, put it in the `plugins` directory. If you don't want your +module to be exported globally but only want it to be used by other +modules, then put it in the `modules` directory instead. If you've +used previous versions of ScriptCraft and have put your custom +javascript modules in the `js-plugins` directory, then put them in the +`scriptcraft/plugins` directory. To summarise, modules in this directory are ... + + * Automatically loaded and run at server startup. + * Anything exported by modules becomes a global variable. + +### The modules directory + +The module directory is where you should place your modules if you +don't want to export globally. In javascript, it's considered best +practice not to have too many global variables, so if you want to +develop modules for others to use, or want to develop more complex +mods then your modules should be placed in the `modules` directory. +*Modules in the `modules` directory are not automatically loaded at +startup*, instead, they are loaded and used by other modules/plugins +using the standard `require()` function. This is the key difference +between modules in the `plugins` directory and modules in the +`modules` directory. Modules in the `plugins` directory are +automatically loaded and exported in to the global namespace at server +startup, modules in the `modules` directory are not. + +### The lib directory + +Modules in the `lib` directory are for use by ScriptCraft and some +core functions for use by module and plugin developers are also +provided. The `lib` directory is for internal use by ScriptCraft. +Modules in this directory are not automatically loaded nor are they +globally exported. + +### plugins sub-directories + +As of December 24 2013, the `scriptcraft/plugins` directory has the following sub-directories... + + * drone - Contains the drone module and drone extensions. Drone was the first scriptcraft module. + * mini-games - Contains mini-games + * arrows - The arrows module - Changes the behaviour of Arrows: Explosive, Fireworks, Teleportation etc. + * signs - The signs module (includes example signs) - create interactive signs. + * chat - The chat plugin/module + * alias - The alias plugin/module - for creating custom aliases for commonly-used commands. + * home - The home module - for setting homes and visiting other homes. + +## Global variables + +There are a couple of special javascript variables available in ScriptCraft... + +### __plugin variable +The ScriptCraft JavaPlugin object. + +### server variable +The Minecraft Server object + +### self variable +The current player. (Note - this value should not be used in multi-threaded scripts or event-handling code - it's not thread-safe). This variable is only safe to use at the in-game prompt and should *never* be used in modules. For example you can use it here... + + /js console.log(self.name) + +... but not in any javascript module you create yourself or in any +event handling code. `self` is a temporary short-lived variable which +only exists in the context of the in-game or server command prompts. + +### config variable +ScriptCraft configuration - this object is loaded and saved at startup/shutdown. + +### events variable +The events object is used to add new event handlers to Minecraft. + +## Module variables +The following variables are available only within the context of Modules. (not available at in-game prompt). + +### __filename variable +The current file - this variable is only relevant from within the context of a Javascript module. + +### __dirname variable +The current directory - this variable is only relevant from within the context of a Javascript module. + +## Global functions + +ScripCraft provides some global functions which can be used by all plugins/modules... + +### echo function + +The `echo()` function displays a message on the in-game screen. + +#### Example + + /js echo( self, 'Hello World') + +For programmers familiar with Javascript web programming, an `alert` +function is also provided. `alert` works exactly the same as `echo` +e.g. `alert( self, 'Hello World')`. + +### require() function + +ScriptCraft's `require()` function is used to load modules. The `require()` function takes a module name as a parameter and will try to load the named module. + +#### Parameters + + * modulename - The name of the module to be loaded. Can be one of the following... + + - A relative file path (with or without `.js` suffix) + - An absolute file path (with or without `.js` suffix) + - A relative directory path (uses node.js rules for directories) + - An absolute directory path (uses node.js rules for directories) + - A name of the form `'events'` - in which case the `lib` directory and `modules` directories are searched for the module. + +#### Return + +require() will return the loaded module's exports. + +### scload() function + +#### No longer recommended for use by Plugin/Module developers (deprecated) + +scload() should only be used to load .json data. + +#### Parameters + + * filename - The name of the file to load. + * warnOnFileNotFound (optional - default: false) - warn if the file was not found. + +#### Returns + +scload() will return the result of the last statement evaluated in the file. + +#### Example + + scload("myFile.js"); // loads a javascript file and evaluates it. + + var myData = scload("myData.json"); // loads a javascript file and evaluates it - eval'd contents are returned. + +##### myData.json contents... + + { players: { + walterh: { + h: ["jsp home {1}"], + sunny:["time set 0", + "weather clear"] + } + } + } + +### scsave() function + +The scsave() function saves an in-memory javascript object to a +specified file. Under the hood, scsave() uses JSON (specifically +json2.js) to save the object. There will usually be no need to call +this function directly - If you want to have a javascript object +automatically loaded at startup and saved on shutdown then use the +`persist()` module. The `persist()` module uses scsave and scload +under the hood. Any in-memory object saved using the `scsave()` +function can later be restored using the `scload()` function. + +#### Parameters + + * objectToSave : The object you want to save. + * filename : The name of the file you want to save it to. + +#### Example + +```javascript +var myObject = { name: 'John Doe', + aliases: ['John Ray', 'John Mee'], + date_of_birth: '1982/01/31' }; +scsave(myObject, 'johndoe.json'); +``` + +##### johndoe.json contents... + + { "name": "John Doe", + "aliases": ["John Ray", "John Mee"], + "date_of_birth": "1982/01/31" + }; + +### plugin() function + +#### Update April 2015 +The `plugin()` function is deprecated. Please refer to [Anatomy of a +ScriptCraft Plugin][anatomy] for an up-to-date step-by-step guide to +creating a plugin which uses persistence (loading and saving data). + +#### Deprecated +The `plugin()` function should be used to declare a javascript module +whose state you want to have managed by ScriptCraft - that is - a +Module whose state will be loaded at start up and saved at shut down. +A plugin is just a regular javascript object whose state is managed by +ScriptCraft. The only member of the plugin which whose persistence is +managed by Scriptcraft is `store` - this special member will be +automatically saved at shutdown and loaded at startup by +ScriptCraft. This makes it easier to write plugins which need to +persist data. + +#### Parameters + + * pluginName (String) : The name of the plugin - this becomes a global variable. + * pluginDefinition (Object) : The various functions and members of the plugin object. + * isPersistent (boolean - optional) : Specifies whether or not the + plugin/object state should be loaded and saved by ScriptCraft. + +#### Example + +See chat/color.js for an example of a simple plugin - one which lets +players choose a default chat color. See also [Anatomy of a +ScriptCraft Plugin][anatomy]. + +[anatomy]: ./Anatomy-of-a-Plugin.md + +### command() function + +The `command()` function is used to expose javascript functions for use by non-operators (regular players). Only operators should be allowed use raw javascript using the `/js ` command because it is too powerful for use by regular players and can be easily abused. However, the `/jsp ` command lets you (the operator / server administrator / plugin author) safely expose javascript functions for use by players. + +#### Parameters + + * commandFunction: The named javascript function which will be invoked when the command is invoked by a player. The name of the function will be used as the command name so name this function accordingly. The callback function in turn takes 2 parameters... + + * params : An Array of type String - the list of parameters passed to the command. + * sender : The [CommandSender][bukcs] object that invoked the command (this is usually a Player object but can be a Block ([BlockCommandSender][bukbcs]). + + * options (Array|Function - optional) : An array of command options/parameters which the player can supply (It's useful to supply an array so that Tab-Completion works for the `/jsp ` commands. If a function is supplied instead of an array then the function will be invoked at TAB-completion time and should return an array of strings. + * intercepts (boolean - optional) : Indicates whether this command can intercept Tab-Completion of the `/jsp ` command - advanced usage - see alias/alias.js for example. + +#### Example + + // javascript code + function boo( params, sender) { + echo( sender, params[0] ); + } + command( boo ); + + # in-game execution + /jsp boo Hi! + > Hi! + +To use a callback for options (TAB-Completion) ... + + var utils = require('utils'); + function boo( params, sender ) { + var receiver = server.getPlayer( params[0] ); + if ( receiver ){ + echo( receiver, sender.name + ' says boo!'); + } + } + command( boo, utils.playerNames ); + +See chat/colors.js or alias/alias.js or homes/homes.js for more examples of how to use the `command()` function. + +### setTimeout() function + +This function mimics the setTimeout() function used in browser-based javascript. However, the function will only accept a function reference, not a string of javascript code. Where setTimeout() in the browser returns a numeric value which can be subsequently passed to clearTimeout(), This implementation returns an object which can be subsequently passed to ScriptCraft's own clearTimeout() implementation. + +If Node.js supports setTimeout() then it's probably good for ScriptCraft to support it too. + +#### Example + +```javascript +// +// start a storm in 5 seconds +// +setTimeout( function() { + var world = server.worlds.get(0); + world.setStorm(true); +}, 5000); +``` + +### clearTimeout() function + +A scriptcraft implementation of clearTimeout(). + +### setInterval() function + +This function mimics the setInterval() function used in browser-based javascript. However, the function will only accept a function reference, not a string of javascript code. Where setInterval() in the browser returns a numeric value which can be subsequently passed to clearInterval(), This implementation returns an object which can be subsequently passed to ScriptCraft's own clearInterval() implementation. + +### clearInterval() function + +A scriptcraft implementation of clearInterval(). + +### refresh() function + +The refresh() function can be used to only reload the ScriptCraft plugin (it's like the `reload` command except it only reloads ScriptCraft). The refresh() function will ... + +1. Disable the ScriptCraft plugin. +2. Unload all event listeners associated with the ScriptCraft plugin. +3. Enable the ScriptCraft plugin. + +... refresh() can be used during development to reload only scriptcraft javascript files. +See [issue #69][issue69] for more information. + +[issue69]: https://github.com/walterhiggins/ScriptCraft/issues/69 + +### addUnloadHandler() function + +The addUnloadHandler() function takes a callback function as a parameter. The callback will be called when the ScriptCraft plugin is unloaded (usually as a result of a a `reload` command or server shutdown). + +This function provides a way for ScriptCraft modules to do any required cleanup/housekeeping just prior to the ScriptCraft Plugin unloading. + +### isOp() function + +This function takes a single parameter and returns true if it's an operator or has operator-level privileges. + +***/ + +/* + wph 20130124 - make self, plugin and server public - these are far more useful now that tab-complete works. +*/ +var global = this; +var server; +global.nashorn = typeof Java !== 'undefined'; +/* + private implementation +*/ +var __onDisableImpl; +function __onDisable ( __engine, __plugin ) { + __onDisableImpl( __engine, __plugin); +} +function __onEnable ( __engine, __plugin, __script ) { + function _echo( ) { + var sender, msg; + if (arguments.length == 2){ + sender = arguments[0]; + msg = arguments[1]; + } else { + if ( typeof self == 'undefined' ) { + return; + } + sender = self; + msg = arguments[0]; + } + if (__plugin.canary){ + sender.message( msg ); + } else { + sender.sendMessage( msg ); + } + } // end echo() + function _canonize( file ) { + return '' + file.getCanonicalPath().replaceAll( '\\\\', '/' ); + } + /* + Save a javascript object to a file (saves using JSON notation) + */ + function _save( objToSave, filename ) { + var objectToStr = null, + f, + out; + try { + objectToStr = JSON.stringify( objToSave, null, 2 ); + + } catch( e ) { + console.error( 'ERROR: ' + e.getMessage() + ' while saving ' + filename ); + return; + } + f = (filename instanceof File) ? filename : new File(filename); + out = new PrintWriter(new FileWriter(f)); + out.println( objectToStr ); + out.close(); + } + function _loadJSON( filename ){ + var result = null, + file = filename, + r, + reader, + br, + contents; + + if ( !( filename instanceof File ) ) { + file = new File(filename); + } + var canonizedFilename = _canonize( file ); + + if ( file.exists() ) { + reader = new FileReader( file ); + br = new BufferedReader( reader ); + contents = ''; + try { + while ( (r = br.readLine()) !== null ) { + contents += r + '\n'; + } + result = JSON.parse(contents); + } catch ( e ) { + logError('Error evaluating ' + canonizedFilename + ', ' + e ); + } + finally { + try { + reader.close(); + } catch ( re ) { + // fail silently on reader close error + } + } + } + return result; + } + /* + Load the contents of the file and evaluate as javascript + */ + function _load( filename, warnOnFileNotFound ) + { + var result = null, + file = filename, + r, + parent, + reader, + br, + code, + wrappedCode; + + if ( !( filename instanceof File ) ) { + file = new File(filename); + } + var canonizedFilename = _canonize( file ); + + if ( file.exists() ) { + reader = new FileReader( file ); + br = new BufferedReader( reader ); + code = ''; + try { + while ( (r = br.readLine()) !== null ) { + code += r + '\n'; + } + wrappedCode = '(' + code + ')'; + result = __engine.eval( wrappedCode ); + // issue #103 avoid side-effects of || operator on Mac Rhino + } catch ( e ) { + logError('Error evaluating ' + canonizedFilename + ', ' + e ); + } + finally { + try { + reader.close(); + } catch ( re ) { + // fail silently on reader close error + } + } + } else { + if ( warnOnFileNotFound ) { + logWarn(canonizedFilename + ' not found' ); + } + } + return result; + } // end _load() + + function _isOp( sender ){ + if (__plugin.canary){ + return sender.receiverType.name() == 'SERVER' || Canary.ops().isOpped(sender); + } else { + return sender.op; + } + } + function _refresh( ) { + if ( typeof self !== 'undefined' ) { + if ( !_isOp(self) ) { + echo( self, 'Only operators can refresh()'); + return; + } + } + if (__plugin.canary){ + var pluginName = __plugin.name; + Canary.manager().disablePlugin( pluginName ); + Canary.manager().enablePlugin( pluginName ); + } else { + __plugin.pluginLoader.disablePlugin( __plugin ); + __plugin.pluginLoader.enablePlugin( __plugin ); + } + } // end _refresh() + function _onDisable( evt ) { + // save config + _save( global.config, new File( jsPluginsRootDir, 'data/global-config.json' ) ); + _runUnloadHandlers(); + } + function _addUnloadHandler( f ) { + unloadHandlers.push( f ); + } + function _runUnloadHandlers() { + for ( var i = 0; i < unloadHandlers.length; i++ ) { + unloadHandlers[i]( ); + } + } + function __onCommand() { + var jsArgs = [], + i = 0, + jsResult, + result, + cmdName, + sender, + args, + cmd, + label, + fnBody; + + if ( __plugin.canary ) { + sender = arguments[0]; + args = arguments[1]; + cmdName = (''+args[0]).toLowerCase().replace(/^\//,''); + for ( i = 1; i < args.length ; i++ ) { + jsArgs.push( '' + args[i] ); + } + } else { + sender = arguments[0]; + cmd = arguments[1]; + label = arguments[2]; + args = arguments[3]; + cmdName = ( '' + cmd.name ).toLowerCase(); + for ( ; i < args.length ; i++ ) { + jsArgs.push( '' + args[i] ); + } + } + result = false; + + if (cmdName == 'js') + { + result = true; + fnBody = jsArgs.join(' '); + global.self = sender; + global.__engine = __engine; + try { + // cannot rely on native eval in jre7 and jre8 + // because ... + // js var hearts + // js hearts + // ... throws an execption ('hearts' is not defined). vars are not sticky in native eval . + // + jsResult = __engine.eval( fnBody ); + + if ( typeof jsResult != 'undefined' ) { + if ( jsResult == null) { + // engine eval will return null even if the result should be undefined + // this can be confusing so I think it's better to omit output for this case + // sender.sendMessage('(null)'); + } else { + try { + if ( isJavaObject(jsResult) || typeof jsResult === 'function') { + echo(sender, jsResult); + } else { + var replacer = function replacer(key, value){ + return this[key] instanceof java.lang.Object ? '' + this[key] : value; + }; + echo(sender, JSON.stringify( jsResult, replacer, 2) ); + } + } catch ( displayError ) { + logError('Error while trying to display result: ' + jsResult + ', Error: '+ displayError) ; + } + } + } + } catch ( e ) { + logError( 'Error while trying to evaluate javascript: ' + fnBody + ', Error: '+ e ); + echo( sender, 'Error while trying to evaluate javascript: ' + fnBody + ', Error: '+ e ); + throw e; + } finally { + /* + wph 20140312 don't delete self on nashorn until https://bugs.openjdk.java.net/browse/JDK-8034055 is fixed + */ + if ( !nashorn ) { + delete global.self; + delete global.__engine; + } + } + } + if ( cmdName == 'jsp' ) { + cmdModule.exec( jsArgs, sender ); + result = true; + } + return result; + } // end __onCommand() function + + var Bukkit = null; + var Canary = null; + var logger = null; + + if (__plugin.canary){ + Canary = Packages.net.canarymod.Canary; + server = Canary.server; + logger = __plugin.logman; + } else { + Bukkit = Packages.org.bukkit.Bukkit; + server = Bukkit.server; + logger = __plugin.logger; + } + function logError(msg){ + __plugin.canary ? logger.error( msg ) : logger.severe( msg ); + } + function logWarn(msg){ + __plugin.canary ? logger.warn( msg ) : logger.warning( msg ); + } + var File = java.io.File, + FileReader = java.io.FileReader, + BufferedReader = java.io.BufferedReader, + PrintWriter = java.io.PrintWriter, + FileWriter = java.io.FileWriter, + // assumes scriptcraft.js is in mcserver/plugins/scriptcraft/lib directory + jsPluginsRootDir = __script.parentFile.parentFile, + jsPluginsRootDirName = _canonize(jsPluginsRootDir), + unloadHandlers = []; + + /* + make sure eval is present: it's present on JRE 6, 7, and 8 on Linux + */ + if ( typeof eval == 'undefined' ) { + global.eval = function( str ) { + return __engine.eval( str ); + }; + } + + /* + now that load is defined, use it to load a global config object + */ + var configFile = new File(jsPluginsRootDir, 'data/'); + configFile.mkdirs(); + configFile = new File(configFile,'global-config.json'); + var config = _load( configFile ); + if ( !config ) { + config = { verbose: false }; + } + global.config = config; + global.__plugin = __plugin; + /* + wph 20131229 Issue #103 JSON is not bundled with javax.scripting / Rhino on Mac. + */ + (function(){ + var jsonFileReader = new FileReader( new File( jsPluginsRootDirName + '/lib/json2.js' ) ); + var jsonLoaded = __engine['eval(java.io.Reader)']( jsonFileReader ); + }()); + + global.addUnloadHandler = _addUnloadHandler; + global.refresh = _refresh; + global.echo = _echo; + global.alert = _echo; + global.scload = _load; + global.scsave = _save; + global.scloadJSON = _loadJSON; + global.isOp = _isOp; + var configRequire = _load( jsPluginsRootDirName + '/lib/require.js', true ); + /* + setup paths to search for modules + */ + var modulePaths = [ jsPluginsRootDirName + '/lib/', + jsPluginsRootDirName + '/modules/' ]; + + if ( config.verbose ) { + logger.info( 'Setting up CommonJS-style module system. Root Directory: ' + jsPluginsRootDirName ); + logger.info( 'Module paths: ' + JSON.stringify(modulePaths) ); + } + var requireHooks = { + loading: function( path ) { + if ( config.verbose ) { + logger.info( 'loading ' + path ); + } + }, + loaded: function( path ) { + if ( config.verbose ) { + logger.info( 'loaded ' + path ); + } + } + }; + global.require = configRequire( + jsPluginsRootDirName, + modulePaths, + requireHooks, + function( code ) { + return __engine.eval( code ); + } + ); + + var testJSPatch = require('js-patch')( global ); + var console = require('console')(logger); + global.console = console; + testJSPatch(console); + + /* + setup persistence + */ + require('persistence')( jsPluginsRootDir, global ); + + var isJavaObject = require('java-utils').isJavaObject; + + var cmdModule = require('command'); + global.command = cmdModule.command; + var plugins = require('plugin'); + global.__onTabComplete = require('tabcomplete'); + global.plugin = plugins.plugin; + + var events = require('events'); + // wph 20131226 - make events global as it is used by many plugins/modules + global.events = events; + + if (__plugin.canary) { + // canary plugin doesn't get to handle its own plugin disable event + } else { + events.pluginDisable(_onDisable); + } + __onDisableImpl = _onDisable; + global.__onCommand = __onCommand; + plugins.autoload( global, new File(jsPluginsRootDir,'plugins') ); + require('legacy-check')(jsPluginsRootDir); +} diff --git a/server/scriptcraft/lib/tabcomplete-jsp.js b/server/scriptcraft/lib/tabcomplete-jsp.js new file mode 100755 index 0000000..1928b39 --- /dev/null +++ b/server/scriptcraft/lib/tabcomplete-jsp.js @@ -0,0 +1,48 @@ +'use strict'; +var _commands = require('command').commands; +/* + Tab completion for the /jsp commmand +*/ +var __onTabCompleteJSP = function( result, cmdArgs ) { + var cmdInput = cmdArgs[0], + opts, + cmd, + len, + i; + cmd = _commands[cmdInput]; + if ( cmd ) { + if (typeof cmd.options === 'function'){ + opts = cmd.options(); + } else { + opts = cmd.options; + } + len = opts.length; + if ( cmdArgs.length > 1 ) { + // partial e.g. /jsp chat_color dar + for ( i = 0; i < len; i++ ) { + if ( opts[i].indexOf( cmdArgs[1] ) == 0 ) { + result.add( opts[i] ); + } + } + } + } else { + if ( cmdArgs.length == 0 ) { + for ( i in _commands ) { + result.add( i ); + } + } else { + // partial e.g. /jsp ho + // should tabcomplete to home + // + for ( i in _commands ) { + if ( i.indexOf( cmdInput ) == 0 ) { + result.add( i ); + } + } + } + } + return result; +}; +module.exports = __onTabCompleteJSP; + + diff --git a/server/scriptcraft/lib/tabcomplete.js b/server/scriptcraft/lib/tabcomplete.js new file mode 100755 index 0000000..fd7a00c --- /dev/null +++ b/server/scriptcraft/lib/tabcomplete.js @@ -0,0 +1,255 @@ +'use strict'; +var tabCompleteJSP = require('tabcomplete-jsp'), + isJavaObject = require('java-utils').isJavaObject; + +/* + Tab Completion of the /js and /jsp commands +*/ +var _javaLangObjectMethods = [ + 'equals' + ,'getClass' + ,'class' + ,'getClass' + ,'hashCode' + ,'notify' + ,'notifyAll' + ,'toString' + ,'wait' + ,'clone' + ,'finalize' +]; + +var _getProperties = function( o ) { + var result = [], + i, + j, + isObjectMethod, + propValue, + typeofProperty; + + if ( isJavaObject( o ) ) { + /* + fix for issue #115 - java objects are not iterable + see: http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-March/002790.html + */ + if ( typeof Object.bindProperties === 'function' ) { + var placeholder = {}; + Object.bindProperties(placeholder, o); + o = placeholder; + } + propertyLoop: + for ( i in o ) { + // + // don't include standard Object methods + // + isObjectMethod = false; + for ( j = 0; j < _javaLangObjectMethods.length; j++ ) { + if ( _javaLangObjectMethods[j] == i ) { + continue propertyLoop; + } + } + typeofProperty = null; + try { + propValue = o[i]; + typeofProperty = typeof propValue; + } catch( e ) { + if ( e.message == 'java.lang.IllegalStateException: Entity not leashed' ) { + // wph 20131020 fail silently for Entity leashing in craftbukkit + } else { + // don't throw an error during tab completion just make a best effort to + // do the job. + } + } + if ( typeofProperty == 'function' ) { + result.push( i+'()' ); + } else { + result.push( i ); + } + } + } else { + if ( o.constructor == Array ) { + return result; + } + for ( i in o ) { + if ( i.match( /^[^_]/ ) ) { + if ( typeof o[i] == 'function'){ + if ( ! (o[i] instanceof java.lang.Object) ) { + try { + if (o[i].constructor){} // throws error for java objects in jre7 + result.push(i + '()'); + } catch (e ){ + result.push(i); + } + + }else { + result.push( i ); + } + } else { + result.push( i ); + } + } + } + } + return result.sort(); +}; + +var onTabCompleteJS = function( ) { + + var _globalSymbols, + lastArg, + propsOfLastArg, + statement, + statementSyms, + lastSymbol, + parts, + name, + symbol, + lastGoodSymbol, + lastArgProp, + i, + objectProps, + candidate, + re, + li, + possibleCompletion, + result, + cmdSender, + pluginCmd, + cmdArgs; + + result = arguments[0]; + cmdSender = arguments[1]; + if (__plugin.bukkit){ + pluginCmd = arguments[2].name; + cmdArgs = arguments[4]; + } + if (__plugin.canary){ + cmdArgs = arguments[2]; + pluginCmd = arguments[3]; + } + cmdArgs = Array.prototype.slice.call( cmdArgs, 0 ); + + if (__plugin.canary){ + // if 1st element is 'js' then splice + // there's probably a better way to do this + if (cmdArgs[0] == 'js'){ + cmdArgs = cmdArgs.slice(1); + } + } + if ( pluginCmd == 'jsp' ) { + return tabCompleteJSP( result, cmdArgs ); + } + + global.self = cmdSender; // bring in self just for autocomplete + + _globalSymbols = _getProperties(global); + + lastArg = cmdArgs.length ? cmdArgs[ cmdArgs.length - 1 ] + '' : null; + propsOfLastArg = []; + statement = cmdArgs.join(' '); + + statement = statement.replace(/^\s+/,'').replace(/\s+$/,''); + + if ( statement.length == 0 ) { + propsOfLastArg = _globalSymbols; + } else { + if (statement.match(/\)$/)){ + return; + } + statementSyms = statement.split(/[^\$a-zA-Z0-9_\.]/); + + lastSymbol = statementSyms[statementSyms.length-1]; + //print('DEBUG: lastSymbol=[' + lastSymbol + ']'); + // + // try to complete the object ala java IDEs. + // + parts = lastSymbol.split(/\./); + name = parts[0]; + + symbol = global[name]; + + //print('DEBUG: name=' + name + ',symbol=' + symbol); + + lastGoodSymbol = symbol; + if ( typeof symbol !== 'undefined' ) { + for ( i = 1; i < parts.length; i++ ) { + name = parts[i]; + if ( !name ) { // fix issue #115 + break; + } + try { + // this causes problems in jre if symbol is an enum and name is partial-match + symbol = symbol[name]; // this causes problem in jre8 if name is '' + } catch (e){ + symbol = null; + break; + } + if ( typeof symbol == 'undefined' ) { + break; + } + // nashorn - object[missingProperty] returns null not undefined + if ( symbol == null ) { + break; + } + lastGoodSymbol = symbol; + } + if ( typeof symbol == 'undefined' || symbol === null) { + // + // look up partial matches against last good symbol + // + objectProps = _getProperties( lastGoodSymbol ); + if ( name == '' ) { + // if the last symbol looks like this.. + // server. + // + //print('debug:case Y1: server.'); + + for ( i = 0; i < objectProps.length; i++ ) { + candidate = lastSymbol + objectProps[i]; + re = new RegExp( lastSymbol + '$', 'g' ); + propsOfLastArg.push( lastArg.replace( re, candidate ) ); + } + + } else { + // it looks like this.. + // server.wo + // + //print('debug:case Y2: server.wo'); + + li = statement.lastIndexOf(name); + for ( i = 0; i < objectProps.length; i++ ) { + if ( objectProps[i].indexOf(name) == 0 ) { + candidate = lastSymbol.substring( 0, lastSymbol.lastIndexOf( name ) ); + candidate = candidate + objectProps[i]; + re = new RegExp( lastSymbol + '$', 'g' ); + propsOfLastArg.push( lastArg.replace( re, candidate ) ); + } + } + } + } else { + //print('debug:case Y3: server'); + objectProps = _getProperties( symbol ); + for ( i = 0; i < objectProps.length; i++ ) { + re = new RegExp( lastSymbol+ '$', 'g' ); + lastArgProp = lastArg.replace( re, lastSymbol + '.' + objectProps[i] ) ; + lastArgProp = lastArgProp.replace(/\.\./g,'.'); + propsOfLastArg.push( lastArgProp ); + } + } + } else { + for ( i = 0; i < _globalSymbols.length; i++ ) { + if ( _globalSymbols[i].indexOf(lastSymbol) == 0 ) { + possibleCompletion = _globalSymbols[i]; + re = new RegExp( lastSymbol+ '$', 'g' ); + propsOfLastArg.push( lastArg.replace( re, possibleCompletion ) ); + } + } + } + } + for ( i = 0; i < propsOfLastArg.length; i++ ) { + result.add( propsOfLastArg[i] ); + } + + delete global.self; // delete self when no longer needed for autocomplete +}; +module.exports = onTabCompleteJS; diff --git a/server/scriptcraft/lib/task-bukkit.js b/server/scriptcraft/lib/task-bukkit.js new file mode 100755 index 0000000..959589d --- /dev/null +++ b/server/scriptcraft/lib/task-bukkit.js @@ -0,0 +1,24 @@ +'use strict'; +/*global __plugin, module, server*/ +function bukkitSetTimeout( callback, delayInMillis ){ + var delay = Math.ceil( delayInMillis / 50 ); + var task = server.scheduler.runTaskLater( __plugin, callback, delay ); + return task; +} +function bukkitClearTimeout( task ) { + task.cancel(); +} +function bukkitSetInterval( callback, intervalInMillis ) { + var delay = Math.ceil( intervalInMillis / 50); + var task = server.scheduler.runTaskTimer( __plugin, callback, delay, delay ); + return task; +} +function bukkitClearInterval( bukkitTask ) { + bukkitTask.cancel(); +} +module.exports = function($){ + $.setTimeout = bukkitSetTimeout; + $.clearTimeout = bukkitClearTimeout; + $.setInterval = bukkitSetInterval; + $.clearInterval = bukkitClearInterval; +}; diff --git a/server/scriptcraft/lib/task-canary.js b/server/scriptcraft/lib/task-canary.js new file mode 100755 index 0000000..cbe2682 --- /dev/null +++ b/server/scriptcraft/lib/task-canary.js @@ -0,0 +1,35 @@ +'use strict'; +/*global Packages, __plugin, module*/ +/* + javascript programmers familiar with setTimeout know that it expects + a delay in milliseconds. However, bukkit's scheduler expects a delay in ticks + (where 1 tick = 1/20th second) + */ +function canarySetTimeout( callback, delayInMillis ){ + var cmTaskManager = Packages.net.canarymod.tasks.ServerTaskManager; + var delay = Math.ceil( delayInMillis / 50 ); + var task = __plugin.createServerTask(callback, delay, false); + cmTaskManager.addTask(task); + return task; +} +function canaryClearTimeout( task ){ + var cmTaskManager = Packages.net.canarymod.tasks.ServerTaskManager; + cmTaskManager.removeTask( task ); +} +function canarySetInterval( callback, intervalInMillis ) { + var cmTaskManager = Packages.net.canarymod.tasks.ServerTaskManager; + var delay = Math.ceil( intervalInMillis / 50 ); + var task = __plugin.createServerTask(callback, delay, true); + cmTaskManager.addTask(task); + return task; +} +function canaryClearInterval( task ){ + var cmTaskManager = Packages.net.canarymod.tasks.ServerTaskManager; + cmTaskManager.removeTask( task ); +} +module.exports = function($){ + $.setTimeout = canarySetTimeout; + $.clearTimeout = canaryClearTimeout; + $.setInterval = canarySetInterval; + $.clearInterval = canaryClearInterval; +}; diff --git a/server/scriptcraft/modules/at.js b/server/scriptcraft/modules/at.js new file mode 100755 index 0000000..03d3384 --- /dev/null +++ b/server/scriptcraft/modules/at.js @@ -0,0 +1,155 @@ +'use strict'; +/*global events, module, require, __plugin, setInterval, clearInterval, setTimeout, addUnloadHandler*/ +var utils = require('utils'); +/************************************************************************ +## The at Module + +The at module provides a single function `at()` which can be used to schedule +repeating (or non-repeating) tasks to be done at a particular time. + +### at() function + +The utils.at() function will perform a given task at a given time in the +(minecraft) day. + +#### Parameters + + * time24hr : The time in 24hr form - e.g. 9:30 in the morning is '09:30' while + 9:30 pm is '21:30', midnight is '00:00' and midday is '12:00' + * callback : A javascript function which will be invoked at the given time. + * worlds : (optional) An array of worlds. Each world has its own clock. If no array of worlds is specified, all the server's worlds are used. + * repeat : (optional) true or false, default is true (repeat the task every day) + +#### Example + +To warn players when night is approaching: + +```javascript +var utils = require('utils'), + at = require('at'); +function warning(){ + utils.players(function( player ) { + echo( player, 'The night is dark and full of terrors!' ); + }); +} +at('19:00', warning); +``` +To run a task only once at the next given time: +```javascript +var utils = require('utils'), + at = require('at'); +function wakeup(){ + utils.players(function( player ) { + echo( player, "Wake Up Folks!" ); + }); +} +at('06:00', wakeup, null, false); +``` + +***/ +var SECOND = 1000; +var POLLING_INTERVAL = 3 * SECOND; // this is probably precise enough + +function at(time24hr, callback, pWorlds, repeat) { + if (arguments.length === 0){ + // TODO: Document this behaviour + console.log(tasksToString()); + return; + } + var timeParts = time24hr.split( ':' ); + var timeMins = (timeParts[0] * 60) + (timeParts[1] * 1); + if (!pWorlds || pWorlds === undefined ) { + pWorlds = utils.worlds(); + } + if (repeat === undefined){ + repeat = true; + } + utils.foreach( pWorlds, function ( world ) { + atAddTask( timeMins, callback, world, repeat); + }); +}; +var atTasks = {}; + +function tasksToString(){ + var result = ''; + for (var world in atTasks){ + result += 'world: ' + world +'\n'; + for (var time in atTasks[world]){ + var scheduledFuncs = atTasks[world][time]; + for (var i = 0;i < scheduledFuncs.length; i++){ + result += ' ' + time + ': ' + scheduledFuncs[i].constructor + '\n'; + } + } + result += '(current world time: ' + utils.time24(world) + ')\n'; + } + return result; +} +/* + constructs a function which will be called every x ticks to + track the schedule for a given world +*/ +function atMonitorFactory(world){ + var worldName = ''+ world.name; + var lastRun = null; + + return function atMonitorForWorld(){ + var timeMins = utils.time24(world); + if (timeMins === lastRun){ + return; + } + if (lastRun === null ){ + lastRun = timeMins - 1; + }else { + lastRun = lastRun % 1440; + } + var worldSchedule = atTasks[worldName]; + if (!worldSchedule){ + return; + } + while ( lastRun > timeMins ? (lastRun <= 1440) : ( lastRun < timeMins ) ){ + + var tasks = worldSchedule[lastRun++]; + if (!tasks){ + continue; + } + utils.foreach(tasks, function(task, i){ + if (!task){ + return; + } + setTimeout(task.callback.bind(null, timeMins, world), 1); + if (!task.repeat){ + tasks[i] = null; + } + }); + } + }; +} +function atAddTask( timeMins, callback, world, repeat){ + var worldName = ''+world.name; + if (!atTasks[worldName]){ + atTasks[worldName] = {}; + } + if (!atTasks[worldName][timeMins]){ + atTasks[worldName][timeMins] = []; + } + atTasks[worldName][timeMins].push({callback: callback, repeat: repeat}); +} +var atMonitors = []; +function onLoadStartMonitor(event){ + var monitor = setInterval( atMonitorFactory(event.world), POLLING_INTERVAL); + atMonitors.push( monitor ); +} +if (__plugin.canary){ + events.loadWorld( onLoadStartMonitor ); +} +if (__plugin.bukkit){ + events.worldLoad( onLoadStartMonitor ); +} + +addUnloadHandler(function(){ + utils.foreach(atMonitors, function(atInterval){ + clearInterval(atInterval); + }); +}); + +module.exports = at; diff --git a/server/scriptcraft/modules/blackboard/index.js b/server/scriptcraft/modules/blackboard/index.js new file mode 100755 index 0000000..f64387f --- /dev/null +++ b/server/scriptcraft/modules/blackboard/index.js @@ -0,0 +1,58 @@ +var utils = require('utils'), + foreach = utils.foreach, + livereload = require('livereload'), + File = java.io.File, + blackboardDir = new File(__dirname + '/../../blackboard/'), + serverAddress = utils.serverAddress(); + +function startBlackboard() { + if (!blackboardDir.exists()) { + blackboardDir.mkdirs(); + } + + runForSubdirs(blackboardDir, function (subdir) { + livereload.enableLiveReloadForDir(subdir, subdir.getName()); + }); +} + +function stopBlackboard() { + runForSubdirs(blackboardDir, function (subdir) { + livereload.disableLiveReloadForDir(subdir); + }); +} + +function runForSubdirs(dir, runnable) { + var files = dir.listFiles(); + if ( !files ) { + return; + } + for ( var i = 0; i < files.length; i++ ) { + var file = files[i]; + if (file.isDirectory( )) { + runnable(file); + } + } +} + +var isOn = false; + +var _blackboard = { + allowScripting: function (/* boolean: true or false */ canScript) { + //Function has no administrative controls + //Intent is that blackboard is used internally from classroom + + if (isOn == canScript) { + //Do nothing, if blackboard is already in desired state + return; + } else { + isOn = canScript; + } + + canScript ? startBlackboard() : stopBlackboard(); + + console.log('Blackboard turned ' + ( canScript ? 'on' : 'off' ) + + ' for all players on server ' + serverAddress); + } +}; + +module.exports = _blackboard; diff --git a/server/scriptcraft/modules/block-colors.js b/server/scriptcraft/modules/block-colors.js new file mode 100755 index 0000000..9c04f65 --- /dev/null +++ b/server/scriptcraft/modules/block-colors.js @@ -0,0 +1,19 @@ +var colors = { + white: 0, + orange: 1, + magenta: 2, + lightblue: 3, + yellow: 4, + lime: 5, + pink: 6, + gray: 7, + lightgray: 8, + cyan: 9, + purple: 10, + blue: 11, + brown: 12, + green: 13, + red: 14, + black: 15 +}; +module.exports = colors; diff --git a/server/scriptcraft/modules/blockhelper.js b/server/scriptcraft/modules/blockhelper.js new file mode 100755 index 0000000..d6831e2 --- /dev/null +++ b/server/scriptcraft/modules/blockhelper.js @@ -0,0 +1,172 @@ +'use strict'; +/*global module, exports, require, Packages, __plugin, server*/ +var blocks = require('blocks'), + bountiful = false; + +if (__plugin.canary){ + bountiful = parseFloat(server.canaryModVersion) > 1.7; +} +if (__plugin.bukkit){ + /* + wph 20150103 - metadata still applies for Craftbukkit 1.8 + bountiful = parseFloat(server.bukkitVersion) > 1.7; + */ +} +var lookup = {}; +function initLookup(){ + var Facing = Packages.net.minecraft.util.EnumFacing, + DyeColor = Packages.net.minecraft.item.EnumDyeColor; + + lookup = { + facing: { + 0: Facing.EAST, + 1: Facing.SOUTH, + 2: Facing.WEST, + 3: Facing.NORTH, + 5: Facing.UP, + east: Facing.EAST, + south: Facing.SOUTH, + west: Facing.WEST, + north: Facing.NORTH, + up: Facing.UP, + down: Facing.DOWN + }, + color: { + black: DyeColor.BLACK, + blue: DyeColor.BLUE, + brown: DyeColor.BROWN, + cyan: DyeColor.CYAN, + gray: DyeColor.GRAY, + green: DyeColor.GREEN, + lightblue: DyeColor.LIGHT_BLUE, + lime: DyeColor.LIME, + magenta: DyeColor.MAGENTA, + orange: DyeColor.ORANGE, + pink: DyeColor.PINK, + purple: DyeColor.PURPLE, + red: DyeColor.RED, + silver: DyeColor.SILVER, + white: DyeColor.WHITE, + yellow: DyeColor.YELLOW, + 0: DyeColor.WHITE, + 1: DyeColor.ORANGE, + 2: DyeColor.MAGENTA, + 3: DyeColor.LIGHT_BLUE, + 4: DyeColor.YELLOW, + 5: DyeColor.LIME, + 6: DyeColor.PINK, + 7: DyeColor.GRAY, + 8: DyeColor.SILVER, + 9: DyeColor.CYAN, + 10: DyeColor.PURPLE, + 11: DyeColor.BLUE, + 12: DyeColor.BROWN, + 13: DyeColor.GREEN, + 14: DyeColor.RED, + 15: DyeColor.BLACK + } + }; +} + +function property( block ){ + var result; + result = { + get: function(p){ + var bp = block.getPropertyForName(p); + return block.getValue(bp); + }, + set: function(name,value){ + var bp = block.getPropertyForName(name); + if (bp === null){ + console.warn(block + ' has no property named ' + name); + return result; + } + if (lookup[bp.name]){ + value = lookup[bp.name][value]; + } + block.setPropertyValue(bp, value); + return result; + } + }; + return result; +} +exports.property = property; +/* + blocks which have facing + */ +function applyFacing( block, metadata ){ + function face(direction){ + property(block).set('facing', lookup.facing[direction]); + } + switch( block.typeId ){ + case blocks.stairs.oak: + case blocks.stairs.cobblestone: + case blocks.stairs.brick: + case blocks.stairs.stone: + case blocks.stairs.nether: + case blocks.stairs.sandstone: + case blocks.stairs.spruce: + case blocks.stairs.jungle: + case blocks.stairs.quartz: + face( ['east','west','south','north'][metadata] ); + break; + case blocks.sign: + case blocks.ladder: + // bug: furnace, chest, dispenser don't always use the right metadata + case blocks.furnace: + case blocks.furnace_burning: + case blocks.chest: + case blocks.enderchest: + case blocks.dispenser: + face( [null,null,'north','south','west','east'][metadata] ); + break; + case blocks.torch: + face( ['up'/* default */,'east','west','south','north','up'][metadata] ); + break; + } +} +function applyColors( block, metadata ){ + switch( block.typeId){ + case blocks.wool.white: + case 35: + case blocks.stained_clay.white: + case 159: + case blocks.stained_glass.white: + case 95: + case blocks.stained_glass_pane.white: + case 160: + case blocks.carpet.white: + case 171: + property(block).set('color',metadata); + } +} +function applyRotation( block, metadata ){ + switch (block.typeId){ + case blocks.sign_post: + if (metadata !== 0){ + property(block).set('rotation', new Packages.java.lang.Integer(metadata)); + } + } +} +function applyVariant( block, metadata ){ + var cmQuartzProperties = Packages.net.canarymod.api.world.blocks.properties.helpers.QuartzProperties; + switch (block.typeId){ + case blocks.quartz: + cmQuartzProperties.applyVariant(block, cmQuartzProperties.Variant.valueOf(metadata)); + break; + } +} +function applyProperties( block, metadata ){ + if (!bountiful){ + block.data = metadata; + return; + } + if (!lookup.facing){ + initLookup(); + } + applyFacing( block, metadata ); + applyColors( block, metadata ); + applyRotation( block, metadata ); + applyVariant( block, metadata ); +} +exports.applyProperties = applyProperties; diff --git a/server/scriptcraft/modules/blocks.js b/server/scriptcraft/modules/blocks.js new file mode 100755 index 0000000..162e82e --- /dev/null +++ b/server/scriptcraft/modules/blocks.js @@ -0,0 +1,329 @@ +/************************************************************************ +## Blocks Module + +You hate having to lookup [Data Values][dv] when you use ScriptCraft's +Drone() functions. So do I. So I created this blocks object which is +a helper object for use in construction. + +### Examples + + box( blocks.oak ); // creates a single oak wood block + box( blocks.sand, 3, 2, 1 ); // creates a block of sand 3 wide x 2 high x 1 long + box( blocks.wool.green, 2 ); // creates a block of green wool 2 blocks wide + +Color aliased properties that were a direct descendant of the blocks +object are no longer used to avoid confusion with carpet and stained +clay blocks. In addition, there's a convenience array `blocks.rainbow` +which is an array of the 7 colors of the rainbow (or closest +approximations). + +The blocks module is globally exported by the Drone module. + +***/ +var colors = require('./block-colors'); + +var blocks = { + air: 0, + stone: 1, + grass: 2, + dirt: 3, + cobblestone: 4, + oak: 5, spruce: '5:1', birch: '5:2', jungle: '5:3', + sapling: { oak: 6, spruce: '6:1', birch: '6:2', jungle: '6:3' }, + bedrock: 7, + water: 8, + water_still: 9, + lava: 10, + lava_still: 11, + sand: 12, + gravel: 13, + gold_ore: 14, + iron_ore: 15, + coal_ore: 16, + wood: 17, + leaves: 18, + sponge: 19, + glass: 20, + lapis_lazuli_ore: 21, + lapis_lazuli_block: 22, + dispenser: 23, + sandstone: 24, + note: 25, + bed: 26, + powered_rail: 27, + detector_rail: 28, + sticky_piston: 29, + cobweb: 30, + grass_tall: 31, + dead_bush: 32, + piston: 33, + piston_extn: 34, piston_head: 34, + wool: { white: 35 /* All other colors added below */ }, + piston_extended: 36, + dandelion: 37, flower_yellow: 37, + rose: 38, flower_red: 38, + mushroom_brown: 39, + mushroom_red: 40, + gold: 41, + iron: 42, + //http://minecraft.gamepedia.com/Data_values#Double_Stone_Slabs + double_slab: { + stone: 43, + sandstone: '43:1', + wooden: '43:2', + cobblestone: '43:3', + brick: '43:4', + stonebrick: '43:5', + netherbrick:'43:6', + quartz: '43:7', + smooth_stone: '43:8', + smooth_sandstone: '43:9', + tile_quartz: '43:15' + }, + slab: { + sandstone: '44:1', + wooden: '44:2', + cobblestone: '44:3', + brick: '44:4', + stonebrick: '44:5', + netherbrick:'44:6', + quartz: '44:7', + upper: { + stone: '44:8', + sandstone: '44:9', + wooden: '44:10', + cobblestone: '44:11', + brick: '44:12', + stonebrick: '44:13', + netherbrick:'44:14', + quartz: '44:15', + oak: '126:8', + spruce: '126:9', + birch: '126:10', + jungle: '126:11' + }, + snow: 78, + stone: 44, + oak: 126, + spruce: '126:1', + birch: '126:2', + jungle: '126:3' + }, + // see brick.red 45 + tnt: 46, + bookshelf: 47, + moss_stone: 48, + obsidian: 49, + torch: 50, + fire: 51, + monster_spawner: 52, + stairs: { + oak: 53, + cobblestone: 67, + brick: 108, + stone: 109, + nether: 114, + sandstone: 128, + spruce: 134, + birch: 135, + jungle: 136, + quartz: 156 + }, + chest: 54, + redstone_wire: 55, + diamond_ore: 56, + diamond: 57, + crafting_table: 58, + wheat_seeds: 59, + farmland: 60, + furnace: 61, + furnace_burning: 62, + sign_post: 63, + door_wood: 64, + ladder: 65, + rail: 66, + sign: 68, + lever: 69, + pressure_plate_stone: 70, + door_iron: 71, + pressure_plate_wood: 72, + redstone_ore: 73, + redstone_ore_glowing: 74, + torch_redstone: 75, + torch_redstone_active: 76, + stone_button: 77, + ice: 79, + snow: 80, + cactus: 81, + clay: 82, + sugar_cane: 83, + jukebox: 84, + fence: 85, + pumpkin: 86, + netherrack: 87, + soulsand: 88, + glowstone: 89, + netherportal: 90, + jackolantern: 91, + cake: 92, + redstone_repeater: 93, + redeston_repeater_active: 94, + stained_glass: { + white: 95 // all other colors added below + }, + trapdoor: 96, + monster_egg: 97, + brick: { + stone: 98, + mossy: '98:1', + cracked: '98:2', + chiseled: '98:3', + red: 45 + }, + mushroom_brown_huge: 99, + mushroom_red_huge: 100, + iron_bars: 101, + glass_pane: 102, + melon: 103, + pumpkin_stem: 104, + melon_stem: 105, + vines: 106, + fence_gate: 107, + mycelium: 110, + lily_pad: 111, + nether: 112, + nether_fence: 113, + netherwart: 115, + table_enchantment: 116, + brewing_stand: 117, + cauldron: 118, + endportal: 119, + endportal_frame: 120, + endstone: 121, + dragon_egg: 122, + redstone_lamp: 123, + redstone_lamp_active: 124, + cocoa: 127, + emerald_ore: 129, + enderchest: 130, + tripwire_hook: 131, + tripwire: 132, + emerald: 133, + command: 137, + beacon: 138, + cobblestone_wall: 139, + flowerpot: 140, + carrots: 141, + potatoes: 142, + button_wood: 143, + skull: 144, mobhead: 144, + anvil: 145, + chest_trapped: 146, + pressure_plate_weighted_light: 147, + pressure_plate_weighted_heavy: 148, + redstone_comparator: 149, + redstone_comparator_active: 150, + daylight_sensor: 151, + redstone: 152, + quartzore: 153, netherquartzore: 153, + hopper: 154, + quartz: 155, + quartz_chiseled: '155:1', + quartz_pillar_vertical: '155:2', + quartz_pillar_horizontal: '155:3', + quartz_pillar_cap: '155:4', + // see stairs.quartz + rail_activator: 157, + dropper: 158, + stained_clay: { + white: 159 // All other colors added below + }, + stained_glass_pane: { + white: 160 // all other colors added below + }, + slime: 165, + barrier: 166, + trapdoor_iron: 167, + prismarine: 168, + prismarine_brick: '168:1', + prismarine_dark: '168:2', + sealantern: 169, + hay: 170, + carpet: { + white: 171 // All other colors added below + }, + hardened_clay: 172, + coal_block: 173, + packed_ice: 174, + double_plant: 175, + sunflower: 175, + flower: { + sunflower: 175, + lilac: '175:1', + tallgrass: '175:2', + fern: '175:3', + rosebush: '175:4', + peony: '175:5', + yellow: 37, + dandelion: 37, + rose: 38, + red: 38 + }, + bonemeal: '351:15', + banner: { + standing: 176, + wallmounted: 177 + }, + daylight_sensor_inverted: 178, + gate: { + spruce: 183, + birch: 184, + jungle: 185, + oak: 186, + acacia: 187 + }, + fence: { + spruce: 188, + birch: 189, + jungle: 190, + oak: 191, + acacia: 192 + } +}; + +// Add all available colors to colorized block collections + +var colorized_blocks = [ + 'wool', + 'stained_clay', + 'carpet', + 'stained_glass', + 'stained_glass_pane' +]; + +for (var i = 0, len = colorized_blocks.length; i < len; i++) { + var block = colorized_blocks[i], + data_value = blocks[block].white; + + for (var color in colors) { + blocks[block][color] = data_value + ':' + colors[color]; + } +}; + +/* + rainbow colors - a convenience + Color aliased properties that were a direct descendant of the blocks + object are no longer used to avoid confusion with carpet and stained + clay blocks. + */ +blocks.rainbow = [ + blocks.stained_glass.red, + blocks.stained_glass.orange, + blocks.stained_glass.yellow, + blocks.stained_glass.lime, + blocks.stained_glass.lightblue, + blocks.stained_glass.blue, + blocks.stained_glass.purple +]; + +module.exports = blocks; diff --git a/server/scriptcraft/modules/bukkit/fireworks.js b/server/scriptcraft/modules/bukkit/fireworks.js new file mode 100755 index 0000000..bf58840 --- /dev/null +++ b/server/scriptcraft/modules/bukkit/fireworks.js @@ -0,0 +1,46 @@ +/* + create a firework at the given location +*/ +function bukkitFirework( location ) { + var bkColor = org.bukkit.Color; + var bkFireworkEffect = org.bukkit.FireworkEffect; + var bkEntityType = org.bukkit.entity.EntityType; + + var randInt = function( n ) { + return Math.floor( Math.random() * n ); + }; + var getColor = function( i ) { + var colors = [ + bkColor.AQUA, bkColor.BLACK, bkColor.BLUE, bkColor.FUCHSIA, bkColor.GRAY, + bkColor.GREEN, bkColor.LIME, bkColor.MAROON, bkColor.NAVY, bkColor.OLIVE, + bkColor.ORANGE, bkColor.PURPLE, bkColor.RED, bkColor.SILVER, bkColor.TEAL, + bkColor.WHITE, bkColor.YELLOW]; + return colors[i]; + }; + var fw = location.world.spawnEntity(location, bkEntityType.FIREWORK); + var fwm = fw.getFireworkMeta(); + var fwTypes = [ + bkFireworkEffect.Type.BALL, + bkFireworkEffect.Type.BALL_LARGE, + bkFireworkEffect.Type.BURST, + bkFireworkEffect.Type.CREEPER, + bkFireworkEffect.Type.STAR + ]; + var type = fwTypes[ randInt( 5 ) ]; + + var r1i = randInt( 17 ); + var r2i = randInt( 17 ); + var c1 = getColor( r1i ); + var c2 = getColor( r2i ); + var effectBuilder = bkFireworkEffect.builder() + .flicker( Math.round( Math.random() ) == 0 ) + .withColor( c1 ) + .withFade( c2 ) + .trail( Math.round( Math.random() ) == 0 ); + effectBuilder['with']( type ); + var effect = effectBuilder.build(); + fwm.addEffect( effect ); + fwm.setPower( randInt( 2 ) + 1 ); + fw.setFireworkMeta( fwm ); +} +module.exports = bukkitFirework; diff --git a/server/scriptcraft/modules/bukkit/input.js b/server/scriptcraft/modules/bukkit/input.js new file mode 100755 index 0000000..c0db662 --- /dev/null +++ b/server/scriptcraft/modules/bukkit/input.js @@ -0,0 +1,28 @@ +var bkPrompt = org.bukkit.conversations.Prompt, + bkConversationFactory = org.bukkit.conversations.ConversationFactory; + +function bukkitAsyncInput( sender, promptMesg, callback) { + var repeat = function(){ + bukkitAsyncInput( sender, promptMesg, callback); + }; + var prompt = new bkPrompt( { + getPromptText: function( ctx ) { + return promptMesg; + }, + acceptInput: function( ctx, value ) { + callback.apply( { repeat: repeat, sender: sender, message: promptMesg, value: value }, + [value, sender, repeat]); + return null; + }, + blocksForInput: function( ctx ) { + return true; + } + }); + + new bkConversationFactory( __plugin ) + .withModality( false ) + .withFirstPrompt( prompt ) + .buildConversation( sender ) + .begin( ); +} +module.exports = bukkitAsyncInput; diff --git a/server/scriptcraft/modules/bukkit/inventory.js b/server/scriptcraft/modules/bukkit/inventory.js new file mode 100755 index 0000000..bba4fea --- /dev/null +++ b/server/scriptcraft/modules/bukkit/inventory.js @@ -0,0 +1,18 @@ +function inventory(entity){ + var inv = entity.inventory; + var result = { + add: function(items){ + inv.addItem([items]); + return result; + }, + remove: function(items){ + inv.removeItem([items]); + return result; + }, + contains: function(items){ + return inv['contains(org.bukkit.inventory.ItemStack)'](items); + } + }; + return result; +} +module.exports = inventory; diff --git a/server/scriptcraft/modules/bukkit/items.js b/server/scriptcraft/modules/bukkit/items.js new file mode 100755 index 0000000..7415295 --- /dev/null +++ b/server/scriptcraft/modules/bukkit/items.js @@ -0,0 +1,29 @@ +/*global require, module, Packages */ +var bkItemStack = Packages.org.bukkit.inventory.ItemStack; +var bkMaterial = Packages.org.bukkit.Material; +var items = function( material, amount ) { + material = material.toUpperCase(); + return new bkItemStack(bkMaterial[material],amount); +}; + +var materials = bkMaterial.values(); + +for (var i = 0;i < materials.length; i++ ){ + var name = (''+materials[i].name()).toLowerCase(); + name = name.replace(/(_.)/g,function(a){ return a.replace(/_/,'').toUpperCase(); }); + + items[name] = (function(material){ + return function(amount){ + if (typeof amount == 'undefined'){ + return material; + } + if (typeof amount == 'number'){ + return new bkItemStack(material, amount); + } else { + return amount == material; + } + }; + })(materials[i]); +} + +module.exports = items; diff --git a/server/scriptcraft/modules/bukkit/recipes.js b/server/scriptcraft/modules/bukkit/recipes.js new file mode 100755 index 0000000..edcb856 --- /dev/null +++ b/server/scriptcraft/modules/bukkit/recipes.js @@ -0,0 +1,15 @@ +var items = require('items'); +var bkShapedRecipe = org.bukkit.inventory.ShapedRecipe; + +exports.add = function( recipe ){ + var result = new bkShapedRecipe( recipe.result ); + result.shape( recipe.shape ); + for (var i in recipe.ingredients ){ + result.setIngredient( i, recipe.ingredients[i] ); + } + server.addRecipe(result); + return result; +}; +exports.remove = function( recipe ) { + server.removeRecipe(recipe); +}; diff --git a/server/scriptcraft/modules/bukkit/sounds.js b/server/scriptcraft/modules/bukkit/sounds.js new file mode 100755 index 0000000..70c08a4 --- /dev/null +++ b/server/scriptcraft/modules/bukkit/sounds.js @@ -0,0 +1,62 @@ +var bkLocation = org.bukkit.Location, + i = 0, + bukkit = require('bukkit'), + foreach = require('utils').foreach, + allSounds = bukkit.sound.values(), + len = allSounds.length, + sound, + soundName; + +for ( ; i < len; i++ ) { + sound = allSounds[i]; + soundName = '' + sound.name(); + var methodName = soundName.toLowerCase().replace(/_(.)/g,function(a,b){ return b.toUpperCase();}); + exports[methodName] = (function(sound){ + return function() + { + switch (arguments.length) { + case 3: + exports.play(sound, arguments[0], arguments[1], arguments[2]); + break; + case 2: + // TODO: possible combinations: + // location, volume, + // volume pitch + exports.play(sound, arguments[0],arguments[1]); + break; + case 1: + exports.play(sound, arguments[0]); + break; + case 0: + // play the sound at full vol, medium pitch for all players + // + foreach(server.onlinePlayers,function(player){ + exports.play(sound, player, 1, 0); + }); + default: + } + }; + })(sound); +} +exports.play = function(sound, locationOrHasLocation, volume, pitch) { + var location = null; + if (!locationOrHasLocation) + return; + if (locationOrHasLocation instanceof bkLocation){ + location = locationOrHasLocation; + } else { + locationOrHasLocation = locationOrHasLocation.location; + if (locationOrHasLocation && locationOrHasLocation instanceof bkLocation ){ + location = locationOrHasLocation; + } + } + if (!location){ + console.warn('sounds.play() needs a location'); + return; + } + if (typeof volume == 'undefined') + volume = 1; + if (typeof pitch == 'undefined') + pitch = 1; + location.world.playSound(location, sound, volume, pitch); +}; diff --git a/server/scriptcraft/modules/canary/fireworks.js b/server/scriptcraft/modules/canary/fireworks.js new file mode 100755 index 0000000..1335c6d --- /dev/null +++ b/server/scriptcraft/modules/canary/fireworks.js @@ -0,0 +1,32 @@ +'use strict'; +/*global require, Packages, module*/ +var items = require('items'); +var Canary = Packages.net.canarymod.Canary; +var cmFireworkHelper = Packages.net.canarymod.api.inventory.helper.FireworkHelper; +var cmExplosionType = Packages.net.canarymod.api.inventory.helper.FireworkHelper.ExplosionType; +var explosionTypes = ['STAR','BURST','CREEPER','LARGE','SMALL']; +var cmDyeColor = Packages.net.canarymod.api.DyeColor; +var entityFactory = Canary.factory().entityFactory; +var cmEntityType = Packages.net.canarymod.api.entity.EntityType; + +function canaryFirework( location ) { + + var firework = items.fireworkStar(1); + cmFireworkHelper.addStarColors( firework, cmDyeColor.values() ); + cmFireworkHelper.setDoesFlicker( firework, true ); + cmFireworkHelper.setDoesTrail( firework, true ); + + // use a random explosion type + var rnd = Math.floor(Math.random() * explosionTypes.length); + var type = explosionTypes[rnd]; + cmFireworkHelper.setStarExplosionType( firework, cmExplosionType[type]); + var rocket = items.fireworkRocket(1); + cmFireworkHelper.setFlightDuration( rocket, 3); + cmFireworkHelper.attachFireworkStars( rocket, [firework] ); + var rocketEntity = entityFactory.newEntity(cmEntityType.FIREWORKROCKET, location); + rocketEntity.item = rocket; + rocketEntity.spawn(); + +} + +module.exports = canaryFirework; diff --git a/server/scriptcraft/modules/canary/input.js b/server/scriptcraft/modules/canary/input.js new file mode 100755 index 0000000..de2ef63 --- /dev/null +++ b/server/scriptcraft/modules/canary/input.js @@ -0,0 +1,26 @@ + +function canaryAsyncInput( sender, promptMesg, callback) { + sender.message(promptMesg); + function repeat(){ + setTimeout( function(){ + listener.unregister(); // avoid CME + canaryAsyncInput( sender, promptMesg, callback); + },1); + } + var listener = events.chat(function (event) { + if (event.player == sender) { + var receivers = event.getReceiverList(); + if (receivers.size() == 1 && receivers.contains(sender)){ + var value = event.message; + var that = this; + event.setCanceled(); + callback.apply( { repeat: repeat, sender: sender, message: promptMesg, value: value }, + [value, sender, repeat]); + setTimeout(function(){that.unregister();},10); + } + } + },'CRITICAL'); + // unregister after 30 seconds + setTimeout(function(){ listener.unregister(); }, 30000); +} +module.exports = canaryAsyncInput; diff --git a/server/scriptcraft/modules/canary/inventory.js b/server/scriptcraft/modules/canary/inventory.js new file mode 100755 index 0000000..4a0d25c --- /dev/null +++ b/server/scriptcraft/modules/canary/inventory.js @@ -0,0 +1,20 @@ +function inventory(entity){ + var inv = entity.inventory; + var result = { + add: function(items){ + inv['addItem(net.canarymod.api.inventory.Item)'](items); + return result; + }, + remove: function(items){ + inv['decreaseItemStackSize(int, int)'](items.id, items.amount); + return result; + }, + contains: function(items){ + var type = items.type; + var amount = items.amount; + return inv['hasItemStack(ItemType, int )'](type, amount); + } + }; + return result; +} +module.exports = inventory; diff --git a/server/scriptcraft/modules/canary/items.js b/server/scriptcraft/modules/canary/items.js new file mode 100755 index 0000000..f943f1d --- /dev/null +++ b/server/scriptcraft/modules/canary/items.js @@ -0,0 +1,70 @@ +/*global nashorn, require, Packages, module*/ +var ItemType = Packages.net.canarymod.api.inventory.ItemType; +var Canary = Packages.net.canarymod.Canary; +var itemFactory = Canary.factory().itemFactory; + +function items( material, amount ) { + material = material.toUpperCase(); + var result = itemFactory["newItem(net.canarymod.api.inventory.ItemType)"](material); + result.amount = amount; + return result; +} +function getMaterialHandler( material ){ + return function(amount){ + if (typeof amount == 'undefined'){ + return material; + } + if (typeof amount == 'number'){ + var itemStack = itemFactory["newItem(net.canarymod.api.inventory.ItemType)"](material); + itemStack.amount = amount; + return itemStack; + } else { + var result = (amount == material); + if (!result){ + if (amount.getId && amount.getData){ + var m2 = ItemType.fromIdAndData(amount.id, amount.data); + result = (m2 == material); + } + } + return result; + } + }; +} +if (nashorn){ + /* + nashorn + */ + var itemTypeClass = require('nashorn-type')(ItemType); + var materials = itemTypeClass.getDeclaredFields(); + var name; + for (var i = 0;i < materials.length; i++ ){ + + if (materials[i].type != itemTypeClass) { + continue; + } + var materialField = materials[i]; + name = (''+materialField.name); + name = name.replace(/^(.)/,function(a){ + return a.toLowerCase(); + }); + + items[name] = getMaterialHandler(materialField.get(ItemType)); + } +} else { + // non-nashorn + for (var field in ItemType){ + if (ItemType[field] === undefined){ + continue; + } + if (!(ItemType[field] instanceof ItemType)){ + continue; + } + name = (''+field).replace(/^(.)/,function(a){ + return a.toLowerCase(); + }); + items[name] = getMaterialHandler(ItemType[field]); + } +} + + +module.exports = items; diff --git a/server/scriptcraft/modules/canary/recipes.js b/server/scriptcraft/modules/canary/recipes.js new file mode 100755 index 0000000..3729291 --- /dev/null +++ b/server/scriptcraft/modules/canary/recipes.js @@ -0,0 +1,48 @@ +var cm = Packages.net.canarymod; +var cmRecipe = cm.api.inventory.recipes.CraftingRecipe; +var cmRecipeRow = cm.api.inventory.recipes.RecipeRow; + +function addRecipe( recipe ){ + return server.addRecipe( createRecipe( recipe ) ); +} +function createRecipe( recipe ){ + if (!recipe){ + return null; + } + var result, + rows, + i,j, + cells, + rr; + if (recipe.shape){ + rows = []; + for (i = 0; i < recipe.shape.length; i++){ + cells = recipe.shape[i].split(''); + rr = []; + for ( j = 0; j < cells.length ; j++){ + if (cells[j] != ' '){ + rr.push(recipe.ingredients[cells[j]]); + } + } + rows.push( new cmRecipeRow(recipe.shape[i], rr) ); + } + /* + wph 20150607 short-term workaround for nashorn defect + https://bugs.openjdk.java.net/browse/JDK-8072596 + */ + if ( typeof Java !== 'undefined' && typeof Java.type === 'function' ) { + var RecipeRowArrayType = Java.type('net.canarymod.api.inventory.recipes.RecipeRow[]'); + rows = Java.to( rows, RecipeRowArrayType ); + } + result = cmRecipe.createShapedRecipe( recipe.result, rows); + } else { + result = cmRecipe.createShapelessRecipe( recipe.result, recipe.ingredients ); + } + return result; +} +function removeRecipe( recipe ){ + server.removeRecipe( recipe ); +} +exports.create = createRecipe; +exports.add = addRecipe; +exports.remove = removeRecipe; diff --git a/server/scriptcraft/modules/canary/sounds.js b/server/scriptcraft/modules/canary/sounds.js new file mode 100755 index 0000000..1d8bcc4 --- /dev/null +++ b/server/scriptcraft/modules/canary/sounds.js @@ -0,0 +1,65 @@ +var allSounds = Packages.net.canarymod.api.world.effects.SoundEffect.Type.values(), + cmSoundEffect = Packages.net.canarymod.api.world.effects.SoundEffect, + foreach = require('utils').foreach, + i = 0, + len = allSounds.length, + sound, + soundName; + +function playSound(sound, locationOrHasLocation, volume, pitch ) { + var location = null; + if (!locationOrHasLocation) + return; + if (locationOrHasLocation.world){ + location = locationOrHasLocation; + } else { + locationOrHasLocation = locationOrHasLocation.location; + if (locationOrHasLocation && locationOrHasLocation.world ){ + location = locationOrHasLocation; + } + } + if (!location){ + console.warn('sounds.play() needs a location'); + return; + } + if (typeof volume == 'undefined') + volume = 1; + if (typeof pitch == 'undefined') + pitch = 1; + var soundEffect = new cmSoundEffect(sound, location.x, location.y, location.z, volume, pitch); + location.world.playSound(soundEffect); +} + +for ( ; i < len; i++ ) { + sound = allSounds[i]; + soundName = '' + sound.name(); + var methodName = soundName.toLowerCase().replace(/_(.)/g,function(a,b){ return b.toUpperCase();}); + exports[methodName] = (function(sound){ + return function() + { + switch (arguments.length) { + case 3: + playSound(sound, arguments[0], arguments[1], arguments[2]); + break; + case 2: + // TODO: possible combinations: + // location, volume, + // volume pitch + playSound(sound, arguments[0],arguments[1]); + break; + case 1: + playSound(sound, arguments[0]); + break; + case 0: + // play the sound at full vol, medium pitch for all players + // + foreach( server.playerList, function(player) { + playSound(sound, player, 1, 0); + }); + default: + } + }; + })(sound); +} + +exports.play = playSound; diff --git a/server/scriptcraft/modules/classroom/index.js b/server/scriptcraft/modules/classroom/index.js new file mode 100755 index 0000000..d337144 --- /dev/null +++ b/server/scriptcraft/modules/classroom/index.js @@ -0,0 +1,207 @@ +'use strict'; +/*global require, module, __plugin, __dirname, echo, persist, isOp, events, Packages, command, global */ +var blackboard = require('blackboard'), + utils = require('utils'), + foreach = utils.foreach, + livereload = require('livereload'), + playersDir = __dirname + '/../../players/', + serverAddress = utils.serverAddress(); + +/************************************************************************ + ## Classroom Plugin + + The `classroom` object contains a couple of utility functions for use + in a classroom setting. The goal of these functions is to make it + easier for tutors to facilitate ScriptCraft for use by students in a + classroom environment. Although granting ScriptCraft access to + students on a shared server is potentially risky (Students can + potentially abuse it), it is slighlty less risky than granting + operator privileges to each student. (Enterprising students will + quickly realise how to grant themselves and others operator privileges + once they have access to ScriptCraft). + + The goal of this module is not so much to enforce restrictions + (security or otherwise) but to make it easier for tutors to setup a + shared server so students can learn Javascript. When scripting is + turned on, every player who joins the server will have a dedicated + directory into which they can save scripts. All scripts in such + directories are automatically watched and loaded into a global + variable named after the player. + + So for example, if player 'walterh' joins the server, a `walterh` + global variable is created. If a file `greet.js` with the following + content is dropped into the `scriptcraft/players/walterh` + directory... + + ```javascript + exports.hi = function( player ){ + echo( player, 'Hi ' + player.name); +}; + ``` + + ... then it can be invoked like this: `/js walterh.hi( self )` . This + lets every player/student create their own functions without having + naming collisions. + + It's strongly recommended that the + `scriptcraft/players/` directory is shared so that + others can connect to it and drop .js files into their student + directories. On Ubuntu, select the folder in Nautilus (the default + file browser) then right-click and choose *Sharing Options*, check the + *Share this folder* checkbox and the *Allow others to create and + delete files* and *Guest access* checkboxes. Click *Create Share* + button to close the sharing options dialog. Students can then access + the shared folder as follows... + + * Windows: Open Explorer, Go to \\{serverAddress}\players\ + * Macintosh: Open Finder, Go to smb://{serverAddress}/players/ + * Linux: Open Nautilus, Go to smb://{serverAddress}/players/ + + ... where {serverAddress} is the ip address of the server (this is + displayed to whoever invokes the classroom.allowScripting() function.) + + ### jsp classroom command + The `jsp classroom` command makes it easy for tutors to turn on or off + classroom mode. This command can only be used by server operators. To + turn on classroom mode (enable scripting for all players): + + jsp classroom on + + To turn off classroom mode (disable scripting for all players): + + jsp classroom off + + The `jsp classroom` command is provided as an easier way to turn on or + off classroom mode. This should be used in preference to the + classroom.allowScripting() function which is provided only for + programmatically enabling or disabling classroom mode. + + ### classroom.allowScripting() function + + Allow or disallow anyone who connects to the server (or is already + connected) to use ScriptCraft. This function is preferable to granting 'ops' privileges + to every student in a Minecraft classroom environment. + + Whenever any file is added/edited or removed from any of the players/ + directories the contents are automatically reloaded. This is to + facilitate quick turnaround time for students getting to grips with + Javascript. + + #### Parameters + + * canScript : true or false + + #### Example + + To allow all players (and any players who connect to the server) to + use the `js` and `jsp` commands... + + /js classroom.allowScripting( true, self ) + + To disallow scripting (and prevent players who join the server from using the commands)... + + /js classroom.allowScripting( false, self ) + + Only ops users can run the classroom.allowScripting() function - this is so that students + don't try to bar themselves and each other from scripting. + + ***/ + +var store = persist('classroom', {enableScripting: false}), + File = java.io.File; + +function grantScripting(player) { + console.log('Enabling scripting for player ' + player.name); + + if (__plugin.bukkit) { + player.addAttachment(__plugin, 'scriptcraft.*', true); + } + if (__plugin.canary) { + player.permissionProvider.addPermission('scriptcraft.evaluate', true); + } + + var playerName = (player.name + '').replace(/[^a-zA-Z0-9_\-]/g, ''); + var playerDir = new File(playersDir + playerName); + + if (!playerDir.exists()) { + playerDir.mkdirs(); + } + + livereload.enableLiveReloadForDir(playerDir, playerName); +} + +function revokeScripting(player) { + console.log('Disabling scripting for player ' + player.name); + + if (__plugin.bukkit) { + foreach(player.getEffectivePermissions(), function (perm) { + if (('' + perm.permission).indexOf('scriptcraft.') == 0) { + if (perm.attachment) { + perm.attachment.remove(); + } + } + }); + } + if (__plugin.canary) { + // + var Canary = Packages.net.canarymod.Canary; + Canary.permissionManager().removePlayerPermission('scriptcraft.evaluate', player); + } + + var playerName = (player.name + '').replace(/[^a-zA-Z0-9_\-]/g, ''); + var playerDir = new File(playersDir + playerName); + + livereload.disableLiveReloadForDir(playerDir); +} + +var _classroom = { + allowScripting: function (/* boolean: true or false */ canScript, sender) { + sender = utils.player(sender); + if (!sender) { + console.log('Attempt to set classroom scripting without credentials'); + console.log('classroom.allowScripting(boolean, sender)'); + return; + } + /* + only operators should be allowed run this function + */ + if (!isOp(sender)) { + console.log('Attempt to set classroom scripting without credentials: ' + sender.name); + echo(sender, 'Only operators can use this function'); + return; + } + utils.players(function (player) { + if (!isOp(player)) { + canScript ? grantScripting(player) : revokeScripting(player); + } + }); + + blackboard.allowScripting(canScript); + + store.enableScripting = canScript; + + echo(sender, 'Scripting turned ' + ( canScript ? 'on' : 'off' ) + + ' for all players on server ' + serverAddress); + } +}; + +if (__plugin.canary) { + events.connection(function (event) { + if (store.enableScripting) { + grantScripting(event.player); + } + }, 'CRITICAL'); +} else { + events.playerJoin(function (event) { + if (store.enableScripting) { + grantScripting(event.player); + } + }, 'HIGHEST'); +} + +if (store.enableScripting) { + //Enable blackboard on startup + blackboard.allowScripting(true); +} + +module.exports = _classroom; \ No newline at end of file diff --git a/server/scriptcraft/modules/drone/arc.js b/server/scriptcraft/modules/drone/arc.js new file mode 100755 index 0000000..6658a37 --- /dev/null +++ b/server/scriptcraft/modules/drone/arc.js @@ -0,0 +1,267 @@ +/*global require*/ +'use strict'; +/************************************************************************ +### Drone.arc() method + +The arc() method can be used to create 1 or more 90 degree arcs in the +horizontal or vertical planes. This method is called by cylinder() and +cylinder0() and the sphere() and sphere0() methods. + +#### Parameters + +arc() takes a single parameter - an object with the following named properties... + + * radius - The radius of the arc. + * blockType - The type of block to use - this is the block Id only (no meta). See [Data Values][dv]. + * meta - The metadata value. See [Data Values][dv]. + * orientation (default: 'horizontal' ) - the orientation of the arc - can be 'vertical' or 'horizontal'. + * stack (default: 1 ) - the height or length of the arc (depending on the orientation - if orientation is horizontal then this parameter refers to the height, if vertical then it refers to the length ). + * strokeWidth (default: 1 ) - the width of the stroke (how many blocks) - if drawing nested arcs it's usually a good idea to set strokeWidth to at least 2 so that there are no gaps between each arc. The arc method uses a [bresenham algorithm][bres] to plot points along the circumference. + * fill - If true (or present) then the arc will be filled in. + * quadrants (default: `{topleft:true,topright:true,bottomleft:true,bottomright:true}` - An object with 4 properties indicating which of the 4 quadrants of a circle to draw. If the quadrants property is absent then all 4 quadrants are drawn. + +#### Examples + +To draw a 1/4 circle (top right quadrant only) with a radius of 10 and +stroke width of 2 blocks ... + + arc({blockType: blocks.iron, + meta: 0, + radius: 10, + strokeWidth: 2, + quadrants: { topright: true }, + orientation: 'vertical', + stack: 1, + fill: false + } ); + +![arc example 1](img/arcex1.png) + +[bres]: http://en.wikipedia.org/wiki/Midpoint_circle_algorithm +[dv]: http://www.minecraftwiki.net/wiki/Data_values + +***/ +/* + do the bresenham thing + */ +function bresenham( x0,y0,radius, setPixel, quadrants ) { + // + // credit: Following code is copied almost verbatim from + // http://en.wikipedia.org/wiki/Midpoint_circle_algorithm + // Bresenham's circle algorithm + // + var f = 1 - radius; + var ddF_x = 1; + var ddF_y = -2 * radius; + var x = 0; + var y = radius; + var defaultQuadrants = {topleft: true, topright: true, bottomleft: true, bottomright: true}; + quadrants = quadrants?quadrants:defaultQuadrants; + /* + II | I + ------------ + III | IV + */ + if ( quadrants.topleft || quadrants.topright ) + setPixel(x0, y0 + radius ); // quadrant I/II topmost + if ( quadrants.bottomleft || quadrants.bottomright ) + setPixel(x0, y0 - radius ); // quadrant III/IV bottommost + if ( quadrants.topright || quadrants.bottomright ) + setPixel(x0 + radius, y0 ); // quadrant I/IV rightmost + if ( quadrants.topleft || quadrants.bottomleft ) + setPixel(x0 - radius, y0 ); // quadrant II/III leftmost + + while ( x < y ) { + if(f >= 0 ) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + if ( quadrants.topright ) { + setPixel(x0 + x, y0 + y ); // quadrant I + setPixel(x0 + y, y0 + x ); // quadrant I + } + if ( quadrants.topleft ) { + setPixel(x0 - x, y0 + y ); // quadrant II + setPixel(x0 - y, y0 + x ); // quadrant II + } + if ( quadrants.bottomleft ) { + setPixel(x0 - x, y0 - y ); // quadrant III + setPixel(x0 - y, y0 - x ); // quadrant III + } + if ( quadrants.bottomright ) { + setPixel(x0 + x, y0 - y ); // quadrant IV + setPixel(x0 + y, y0 - x ); // quadrant IV + } + } +}; + +function getStrokeDir( x,y ) { + var absY = Math.abs(y ); + var absX = Math.abs(x ); + var strokeDir = 0; + if ( y > 0 && absY >= absX ) + strokeDir = 0 ; //down + else if ( y < 0 && absY >= absX ) + strokeDir = 1 ; // up + else if ( x > 0 && absX >= absY ) + strokeDir = 2 ; // left + else if ( x < 0 && absX >= absY ) + strokeDir = 3 ; // right + return strokeDir; +}; + +/* + The daddy of all arc-related API calls - + if you're drawing anything that bends it ends up here. + */ +function arcImpl( params ) { + var drone = params.drone; + var orientation = params.orientation?params.orientation:'horizontal'; + var quadrants = params.quadrants?params.quadrants:{ + topright:1, + topleft:2, + bottomleft:3, + bottomright:4 + }; + var stack = params.stack?params.stack:1; + var radius = params.radius; + var strokeWidth = params.strokeWidth?params.strokeWidth:1; + drone.chkpt('arc2' ); + var x0, y0, gotoxy,setPixel; + + if ( orientation == 'horizontal' ) { + gotoxy = function( x,y ) { return drone.right(x ).fwd(y );}; + drone.right(radius ).fwd(radius ).chkpt('center' ); + switch ( drone.dir ) { + case 0: // east + case 2: // west + x0 = drone.z; + y0 = drone.x; + break; + case 1: // south + case 3: // north + x0 = drone.x; + y0 = drone.z; + } + setPixel = function( x, y ) { + x = ( x-x0 ); + y = ( y-y0 ); + if ( params.fill ) { + // wph 20130114 more efficient esp. for large cylinders/spheres + if ( y < 0 ) { + drone + .fwd( y ).right( x ) + .cuboidX( params.blockType, params.meta, 1, stack, Math.abs( y * 2 ) + 1 ) + .back( y ).left( x ); + } + }else{ + if ( strokeWidth == 1 ) { + gotoxy(x,y ) + .cuboidX( params.blockType, params.meta, + 1, // width + stack, // height + strokeWidth // depth + ) + .move('center' ); + } else { + var strokeDir = getStrokeDir( x, y ); + var width = 1, depth = 1; + switch ( strokeDir ) { + case 0: // down + y = y-( strokeWidth - 1 ); + depth = strokeWidth; + break; + case 1: // up + depth = strokeWidth; + break; + case 2: // left + width = strokeWidth; + x = x-(strokeWidth-1 ); + break; + case 3: // right + width = strokeWidth; + break; + } + gotoxy( x, y ) + .cuboidX( params.blockType, params.meta, width, stack, depth ) + .move( 'center' ); + + } + } + }; + }else{ + // vertical + gotoxy = function( x,y ) { return drone.right(x ).up(y );}; + drone.right(radius ).up(radius ).chkpt('center' ); + switch ( drone.dir ) { + case 0: // east + case 2: // west + x0 = drone.z; + y0 = drone.y; + break; + case 1: // south + case 3: // north + x0 = drone.x; + y0 = drone.y; + } + setPixel = function( x, y ) { + x = ( x - x0 ); + y = ( y - y0 ); + if ( params.fill ) { + // wph 20130114 more efficient esp. for large cylinders/spheres + if ( y < 0 ) { + drone + .up( y ).right( x ) + .cuboidX( params.blockType, params.meta, 1, Math.abs( y * 2 ) + 1, stack ) + .down( y ).left( x ); + } + }else{ + if ( strokeWidth == 1 ) { + gotoxy( x, y ) + .cuboidX( params.blockType, params.meta, strokeWidth, 1, stack ) + .move( 'center' ); + }else{ + var strokeDir = getStrokeDir( x,y ); + var width = 1, height = 1; + switch ( strokeDir ) { + case 0: // down + y = y - ( strokeWidth - 1 ); + height = strokeWidth; + break; + case 1: // up + height = strokeWidth; + break; + case 2: // left + width = strokeWidth; + x = x - ( strokeWidth - 1 ); + break; + case 3: // right + width = strokeWidth; + break; + } + gotoxy(x,y ) + .cuboidX(params.blockType, params.meta, width, height, stack ) + .move('center' ); + + } + } + }; + } + /* + setPixel assumes a 2D plane - need to put a block along appropriate plane + */ + bresenham(x0,y0,radius,setPixel,quadrants ); + + params.drone.move('arc2' ); +}; + +module.exports = function(Drone){ + Drone.extend(function arc( params ) { + params.drone = this; + arcImpl( params ); + }); +}; diff --git a/server/scriptcraft/modules/drone/bed.js b/server/scriptcraft/modules/drone/bed.js new file mode 100755 index 0000000..98442c6 --- /dev/null +++ b/server/scriptcraft/modules/drone/bed.js @@ -0,0 +1,55 @@ +'use strict'; +/*global require, Packages, __plugin, module*/ +var blocks = require('blocks'); +/************************************************************************ +### Drone.bed() method + +Creates a bed. The foot of the bed will be at the drone's location and +the head of the bed will extend away from the drone. + +#### Example +To create a bed at the in-game prompt, look at a block then type: + +```javascript +/js bed() +``` + +Like most Drone methods, this returns the drone so it can be chained like so: + +```javascript +this + .fwd(3) + .bed() + .back(3) +``` +***/ +var bedDirections = { + 0:3, // east + 1:0, // south + 2:1, // west + 3:2 // north +}; +module.exports = function(Drone){ + + Drone.extend( function bed(){ + this.then(function(){ + var foot = this.setBlock(blocks.bed, bedDirections[this.dir], 0,0,0, false); + var head = this.setBlock(blocks.bed, bedDirections[this.dir] + 8, 0,0,1, false); + if (Drone.bountiful){ + var prop = require('blockhelper').property; + var BedHalf = Packages.net.canarymod.api.world.blocks.properties.helpers.BedProperties.Half; + prop(foot) + .set('facing',this.dir) + .set('part', BedHalf.FOOT); + prop(head) + .set('facing',this.dir) + .set('part', BedHalf.HEAD); + } + if (__plugin.canary){ + foot.update(); + head.update(); + } + }); + }); +}; + diff --git a/server/scriptcraft/modules/drone/blocktype.js b/server/scriptcraft/modules/drone/blocktype.js new file mode 100755 index 0000000..5d0311e --- /dev/null +++ b/server/scriptcraft/modules/drone/blocktype.js @@ -0,0 +1,400 @@ +var blocks = require('blocks'); + +/************************************************************************ +### Drone.blocktype() method + +Creates the text out of blocks. Useful for large-scale in-game signs. + +#### Parameters + + * message - The message to create - (use `\n` for newlines) + * foregroundBlock (default: black wool) - The block to use for the foreground + * backgroundBlock (default: none) - The block to use for the background + +#### Example + +To create a 2-line high message using glowstone... + + blocktype('Hello\nWorld', blocks.glowstone); + +![blocktype example][imgbt1] + +[imgbt1]: img/blocktype1.png + +***/ + +var bitmaps = { + raw: { + '0':' ### '+ + ' # # '+ + ' # # '+ + ' # # '+ + ' ### ', + + '1':' # '+ + ' ## '+ + ' # '+ + ' # '+ + ' ### ', + + '2':' ### '+ + ' # '+ + ' ### '+ + ' # '+ + ' ### ', + + '3':' ### '+ + ' # '+ + ' ## '+ + ' # '+ + ' ### ', + + '4':' # '+ + ' ## '+ + ' # # '+ + ' ### '+ + ' # ', + + '5':' ### '+ + ' # '+ + ' ### '+ + ' # '+ + ' ### ', + + '6':' ### '+ + ' # '+ + ' ### '+ + ' # # '+ + ' ### ', + + '7':' ### '+ + ' # '+ + ' # '+ + ' # '+ + ' # ', + + '8':' ### '+ + ' # # '+ + ' ### '+ + ' # # '+ + ' ### ', + + '9':' ### '+ + ' # # '+ + ' ### '+ + ' # '+ + ' ### ', + + 'a':' ### '+ + ' # # '+ + ' ### '+ + ' # # '+ + ' # # ', + + 'b':' ## '+ + ' # # '+ + ' ## '+ + ' # # '+ + ' ## ', + + 'c':' ## '+ + ' # '+ + ' # '+ + ' # '+ + ' ## ', + + 'd':' ## '+ + ' # # '+ + ' # # '+ + ' # # '+ + ' ## ', + + 'e':' ### '+ + ' # '+ + ' ## '+ + ' # '+ + ' ### ', + + 'f':' ### '+ + ' # '+ + ' ## '+ + ' # '+ + ' # ', + + 'g':' ### '+ + ' # '+ + ' # '+ + ' # # '+ + ' ### ', + + 'h':' # # '+ + ' # # '+ + ' ### '+ + ' # # '+ + ' # # ', + + 'i':' ### '+ + ' # '+ + ' # '+ + ' # '+ + ' ### ', + + 'j':' ### '+ + ' # '+ + ' # '+ + ' # '+ + ' # ', + + 'k':' # '+ + ' # # '+ + ' ## '+ + ' # # '+ + ' # # ', + + 'l':' # '+ + ' # '+ + ' # '+ + ' # '+ + ' ### ', + + 'm':' # # '+ + ' ### '+ + ' # # '+ + ' # # '+ + ' # # ', + + 'n':' ## '+ + ' # # '+ + ' # # '+ + ' # # '+ + ' # # ', + + 'o':' # '+ + ' # # '+ + ' # # '+ + ' # # '+ + ' # ', + + 'p':' ### '+ + ' # # '+ + ' ### '+ + ' # '+ + ' # ', + + 'q':' ### '+ + ' # # '+ + ' # # '+ + ' ### '+ + ' # ', + + 'r':' ## '+ + ' # # '+ + ' ## '+ + ' # # '+ + ' # # ', + + 's':' ## '+ + ' # '+ + ' ### '+ + ' # '+ + ' ## ', + + 't':' ### '+ + ' # '+ + ' # '+ + ' # '+ + ' # ', + + 'u':' # # '+ + ' # # '+ + ' # # '+ + ' # # '+ + ' ### ', + + 'v':' # # '+ + ' # # '+ + ' # # '+ + ' # # '+ + ' # ', + + 'w':' # # '+ + ' # # '+ + ' # # '+ + ' ### '+ + ' # # ', + + 'x':' # # '+ + ' # # '+ + ' # '+ + ' # # '+ + ' # # ', + + 'y':' # # '+ + ' # # '+ + ' # # '+ + ' # '+ + ' # ', + + 'z':' ### '+ + ' # '+ + ' # '+ + ' # '+ + ' ### ', + + '!':' # '+ + ' # '+ + ' # '+ + ' '+ + ' # ', + + ':':' '+ + ' # '+ + ' '+ + ' # '+ + ' ', + + ';':' '+ + ' # '+ + ' '+ + ' # '+ + ' # ', + + ',':' '+ + ' '+ + ' '+ + ' # '+ + ' # ', + + '/':' # '+ + ' # '+ + ' # '+ + ' # '+ + ' # ', + + '+':' '+ + ' # '+ + ' ### '+ + ' # '+ + ' ', + + '-':' '+ + ' '+ + ' ### '+ + ' '+ + ' ', + + '.':' '+ + ' '+ + ' '+ + ' '+ + ' # ', + + "'":' # '+ + ' # '+ + ' '+ + ' '+ + ' ', + + ' ':' '+ + ' '+ + ' '+ + ' '+ + ' ' + }, + computed: {} +}; +/* + wph 20130121 compute the width, and x,y coords of pixels ahead of time +*/ +var c, + bits, + width, + bmInfo, + j; +for ( c in bitmaps.raw ) { + bits = bitmaps.raw[c]; + width = bits.length/5; + bmInfo = { width: width, pixels:[] }; + bitmaps.computed[c] = bmInfo; + for ( j = 0; j < bits.length; j++ ) { + if ( bits.charAt(j) != ' ' ) { + bmInfo.pixels.push( [ + j % width, + Math.ceil( j / width ) + ] ); + } + } +} +function blocktype( message, fg, bg, immediate ) { + + var bmfg, + bmbg, + lines, + lineCount, + h, + line, + i, + x, + y, + ch, + bits, + charWidth, + j; + + this.chkpt('blocktext'); + + if ( typeof fg == 'undefined' ) { + fg = blocks.wool.black; + } + + bmfg = this.getBlockIdAndMeta( fg ); + bmbg = null; + if ( typeof bg != 'undefined' ) { + bmbg = this.getBlockIdAndMeta( bg ); + } + lines = message.split( '\n' ); + lineCount = lines.length; + + for ( h = 0; h < lineCount; h++) { + + line = lines[h]; + line = line.toLowerCase().replace( /[^0-9a-z \.\-\+\/\;\'\:\!]/g, '' ); + this.up( 7 * ( lineCount - ( h + 1 ) ) ); + + for ( i =0; i < line.length; i++) { + + ch = line.charAt( i ); + bits = bitmaps.computed[ ch ]; + + if ( typeof bits == 'undefined' ) { + bits = bitmaps.computed[' ']; + } + charWidth = bits.width; + + if ( typeof bg != 'undefined' ) { + this.cuboidX( bmbg[0], bmbg[1], charWidth, 7, 1 , immediate); + } + + for ( j = 0; j < bits.pixels.length; j++ ) { + + this.chkpt( 'btbl' ); + x = bits.pixels[ j ][ 0 ]; + y = bits.pixels[ j ][ 1] ; + this.up( 6 - y ).right( x ).cuboidX( bmfg[ 0 ], bmfg[ 1 ], 1, 1, 1, immediate); + this.move( 'btbl' ); + + } + this.right( charWidth - 1 ); + + } + this.move( 'blocktext' ); + } + + return this.move( 'blocktext' ); +} +module.exports = function(Drone){ + Drone.extend(blocktype); +}; + + + diff --git a/server/scriptcraft/modules/drone/copypaste.js b/server/scriptcraft/modules/drone/copypaste.js new file mode 100755 index 0000000..d6dbb64 --- /dev/null +++ b/server/scriptcraft/modules/drone/copypaste.js @@ -0,0 +1,159 @@ +'use strict'; +/*global require, module*/ + +/************************************************************************ +### Copy & Paste using Drone + +A drone can be used to copy and paste areas of the game world. + +#### Deprecated +As of January 10 2015 the copy-paste functions in Drone are no longer +supported. Copy/Paste is: + +1. Difficult to do correctly in a way which works for both Minecraft 1.7 and 1.8 + due to how blocks changed in 1.8 +2. Not aligned with the purpose of ScriptCraft's Drone module which is to provide + a simple set of functions for scripting and in-game building. + +### Drone.copy() method + +Copies an area so it can be pasted elsewhere. The name can be used for +pasting the copied area elsewhere... + +#### Parameters + + * name - the name to be given to the copied area (used by `paste`) + * width - the width of the area to copy + * height - the height of the area to copy + * length - the length of the area (extending away from the drone) to copy + +#### Example + + drone.copy('somethingCool',10,5,10 ).right(12 ).paste('somethingCool' ); + +### Drone.paste() method + +Pastes a copied area to the current location. + +#### Example + +To copy a 10x5x10 area (using the drone's coordinates as the starting +point) into memory. the copied area can be referenced using the name +'somethingCool'. The drone moves 12 blocks right then pastes the copy. + + drone.copy('somethingCool',10,5,10 ) + .right(12 ) + .paste('somethingCool' ); + +***/ +var clipBoard = {}; + +function paste( name, immediate ){ + console.warn('Drone copy/paste is no longer in active development'); + var Drone = this.constructor; + var ccContent = clipBoard[name]; + if (ccContent == undefined){ + console.warn('Nothing called ' + name + ' in clipboard!'); + return; + } + var srcBlocks = ccContent.blocks; + var srcDir = ccContent.dir; // direction player was facing when copied. + var dirOffset = (4 + (this.dir - srcDir ) ) %4; + + this.traverseWidth(srcBlocks.length,function( ww ) { + var h = srcBlocks[ww].length; + this.traverseHeight(h,function( hh ) { + var d = srcBlocks[ww][hh].length; + this.traverseDepth(d,function( dd ) { + var b = srcBlocks[ww][hh][dd], + cb = b.type, + md = b.data, + newDir, + dir, + a, + c, + len; + // + // need to adjust blocks which face a direction + // + switch ( cb ) { + // + // doors + // + case 64: // wood + case 71: // iron + // top half of door doesn't need to change + if ( md < 8 ) { + md = (md + dirOffset ) % 4; + } + break; + // + // stairs + // + case 53: // oak + case 67: // cobblestone + case 108: // red brick + case 109: // stone brick + case 114: // nether brick + case 128: // sandstone + case 134: // spruce + case 135: // birch + case 136: // junglewood + dir = md & 0x3; + a = Drone.PLAYER_STAIRS_FACING; + len = a.length; + for ( c = 0; c < len; c++ ) { + if ( a[c] == dir ) { + break; + } + } + c = (c + dirOffset ) %4; + newDir = a[c]; + md = (md >>2<<2 ) + newDir; + break; + // + // signs , ladders etc + // + case 23: // dispenser + case 54: // chest + case 61: // furnace + case 62: // burning furnace + case 65: // ladder + case 68: // wall sign + a = Drone.PLAYER_SIGN_FACING; + len = a.length; + for ( c=0; c < len; c++ ) { + if ( a[c] == md ) { + break; + } + } + c = (c + dirOffset ) %4; + newDir = a[c]; + md = newDir; + break; + } + this.setBlock(cb,md); + } ); + } ); + } ); +} +function copy( name, w, h, d ) { + console.warn('Drone copy/paste is no longer in active development'); + var ccContent = []; + this.traverseWidth(w,function( ww ) { + ccContent.push([] ); + this.traverseHeight(h,function( hh ) { + ccContent[ww].push([] ); + this.traverseDepth(d,function( dd ) { + var b = this.getBlock(); + ccContent[ww][hh][dd] = {type:b.getTypeId(), data:b.data}; + } ); + } ); + } ); + clipBoard[name] = {dir: this.dir, blocks: ccContent}; +} + +module.exports = function(Drone){ + Drone.extend( copy ); + Drone.extend( paste ); +}; diff --git a/server/scriptcraft/modules/drone/cylinders.js b/server/scriptcraft/modules/drone/cylinders.js new file mode 100755 index 0000000..cd5094e --- /dev/null +++ b/server/scriptcraft/modules/drone/cylinders.js @@ -0,0 +1,76 @@ +'use strict'; + +/************************************************************************** +### Drone.cylinder() method + +A convenience method for building cylinders. Building begins radius blocks to the right and forward. + +#### Parameters + + * block - the block id - e.g. 6 for an oak sapling or '6:2' for a birch sapling. Alternatively you can use any one of the `blocks` values e.g. `blocks.sapling.birch` + * radius + * height + +#### Example + +To create a cylinder of Iron 7 blocks in radius and 1 block high... + + cylinder(blocks.iron, 7 , 1); + +![cylinder example](img/cylinderex1.png) + +### Drone.cylinder0() method + +A version of cylinder that hollows out the middle. + +#### Example + +To create a hollow cylinder of Iron 7 blocks in radius and 1 block high... + + cylinder0(blocks.iron, 7, 1); + +![cylinder0 example](img/cylinder0ex1.png) + +***/ + +function cylinder0( block,radius,height,exactParams ) { + var arcParams = { + radius: radius, + fill: false, + orientation: 'horizontal', + stack: height + }; + + if ( exactParams ) { + for ( var p in exactParams ) { + arcParams[p] = exactParams[p]; + } + }else{ + var md = this.getBlockIdAndMeta(block ); + arcParams.blockType = md[0]; + arcParams.meta = md[1]; + } + return this.arc(arcParams ); +}; +function cylinder( block,radius,height,exactParams ) { + var arcParams = { + radius: radius, + fill: true, + orientation: 'horizontal', + stack: height + }; + + if ( exactParams ) { + arcParams.blockType = exactParams.blockType; + arcParams.meta = exactParams.meta; + }else{ + var md = this.getBlockIdAndMeta(block ); + arcParams.blockType = md[0]; + arcParams.meta = md[1]; + } + return this.arc(arcParams ); +}; +module.exports = function(Drone){ + Drone.extend(cylinder0 ); + Drone.extend(cylinder ); +}; diff --git a/server/scriptcraft/modules/drone/doors.js b/server/scriptcraft/modules/drone/doors.js new file mode 100755 index 0000000..54f5229 --- /dev/null +++ b/server/scriptcraft/modules/drone/doors.js @@ -0,0 +1,101 @@ +/*global module*/ +'use strict'; +/************************************************************************* +### Drone.door() method + +create a door - if a parameter is supplied an Iron door is created otherwise a wooden door is created. + +#### Parameters + + * doorType (optional - default wood) - If a parameter is provided then the door is Iron. + +#### Example + +To create a wooden door at the crosshairs/drone's location... + + var drone = new Drone(self); + drone.door(); + +To create an iron door... + + drone.door( blocks.door_iron ); + +![iron door](img/doorex1.png) + +### Drone.door_iron() method + +create an Iron door. + +### Drone.door2() method + +Create double doors (left and right side) + +#### Parameters + + * doorType (optional - default wood) - If a parameter is provided then the door is Iron. + +#### Example + +To create double-doors at the cross-hairs/drone's location... + + drone.door2(); + +![double doors](img/door2ex1.png) + +### Drone.door2_iron() method + +Create double iron doors + +***/ + +var blocks = require('blocks'); +/*global require, Packages, __plugin*/ +function door( doorMaterial, hinge) { + if ( typeof doorMaterial == 'undefined' ) { + doorMaterial = blocks.door_wood; // wood + } + if (typeof hinge == 'undefined') { + hinge = 'left'; + } + var Drone = this.constructor; + this.then(function(){ + var lower = this.setBlock(doorMaterial, this.dir, 0, 0, 0, false); + var upper = this.setBlock(doorMaterial, hinge=='left' ? 8 : 9, 0,1,0, false); + if (Drone.bountiful){ + var DoorHalf = Packages.net.minecraft.block.BlockDoor.EnumDoorHalf, + HingePosition = Packages.net.minecraft.block.BlockDoor.EnumHingePosition, + prop = require('blockhelper').property; + prop(lower) + .set('facing', this.dir) + .set('half', DoorHalf.LOWER ); + prop(upper) + .set('hinge', hinge == 'left' ? HingePosition.LEFT: HingePosition.RIGHT) + .set('half', DoorHalf.UPPER); + } + if (__plugin.canary){ + lower.update(); + upper.update(); + } + }); +} +module.exports = function(Drone){ + Drone.extend( door ); + + Drone.extend( function door_iron( ) { + this.door(blocks.door_iron); + } ); + + Drone.extend( function door2( doorMaterial ) { + if ( typeof doorMaterial == 'undefined' ) { + doorMaterial = blocks.door_wood; + } + this + .door( doorMaterial, 'left') + .right() + .door( doorMaterial, 'right') + .left(); + } ); + Drone.extend( function door2_iron( ) { + this.door2( blocks.door_iron ); + } ); +}; diff --git a/server/scriptcraft/modules/drone/firework.js b/server/scriptcraft/modules/drone/firework.js new file mode 100755 index 0000000..764750a --- /dev/null +++ b/server/scriptcraft/modules/drone/firework.js @@ -0,0 +1,21 @@ +'use strict'; +/*global module, require*/ +var fireworks = require('fireworks'); +/************************************************************************* +### Drone.firework() method + +Launches a firework at the drone's location. + +#### Example + +To launch a firework: + + var drone = new Drone(self); + drone.firework(); + +***/ +module.exports = function(Drone){ + Drone.extend( function firework( ) { + fireworks.firework( this.getLocation() ); + }); +}; diff --git a/server/scriptcraft/modules/drone/garden.js b/server/scriptcraft/modules/drone/garden.js new file mode 100755 index 0000000..9baf227 --- /dev/null +++ b/server/scriptcraft/modules/drone/garden.js @@ -0,0 +1,49 @@ +/*global module, require*/ +'use strict'; +/************************************************************************ +### Drone.garden() method + +places random flowers and long grass (similar to the effect of placing bonemeal on grass) + +#### Parameters + + * width - the width of the garden + * length - how far from the drone the garden extends + +#### Example + +To create a garden 10 blocks wide by 5 blocks long... + + garden(10,5); + +![garden example](img/gardenex1.png) + +***/ +var blocks = require('blocks'); + +function garden( width, depth ) { + if ( typeof width == 'undefined' ) { + width = 10; + } + if ( typeof depth == 'undefined' ) { + depth = width; + } + // make sure grass is present first + this + .box( blocks.grass, width, 1, depth ) + .up(); + + // make flowers more common than long grass + var dist = { }; + dist[blocks.rose] = 3; + dist[blocks.dandelion] = 3; + dist[blocks.grass_tall] = 2; + dist[blocks.air] = 1; + + this + .rand( dist, width, 1, depth, false /* don't overwrite */ ) + .down(); +} +module.exports = function(Drone){ + Drone.extend(garden); +}; diff --git a/server/scriptcraft/modules/drone/index.js b/server/scriptcraft/modules/drone/index.js new file mode 100755 index 0000000..5601cb8 --- /dev/null +++ b/server/scriptcraft/modules/drone/index.js @@ -0,0 +1,913 @@ +'use strict'; +/*global __plugin, require, org, setTimeout, addUnloadHandler, global, Packages, server, module*/ +var utils = require('utils'), + blocks = require('blocks'), + THOUSAND = 1000, + MILLION = THOUSAND * THOUSAND; + + +/********************************************************************* +## Drone Plugin + +The Drone is a convenience class for building. + +It uses a fluent interface which means all of the Drone's methods return `this` and can be chained together like so... + + var theDrone = new Drone(self); + theDrone.up().left().box(blocks.oak).down().fwd(3).cylinder0(blocks.lava,8); + +### Constructing a Drone Object + +Drones can be created in any of the following ways... + + 1. Calling any one of the methods listed below will return a Drone object. For example... + + var d = box( blocks.oak ) + + ... creates a 1x1x1 wooden block at the cross-hairs or player's location and returns a Drone object. This might look odd (if you're familiar with Java's Object-dot-method syntax) but all of the Drone class's methods are also global functions that return new Drone objects. This is short-hand for creating drones and is useful for playing around with Drones at the in-game command prompt. It's shorter than typing ... + + var d = new Drone(self).box( blocks.oak ) + + ... All of the Drone's methods return `this` so you can chain operations together like this... + + var d = box( blocks.oak ) + .up() + .box( blocks.oak ,3,1,3) + .down() + .fwd(2) + .box( blocks.oak ) + .turn() + .fwd(2) + .box( blocks.oak ) + .turn() + .fwd(2) + .box( blocks.oak ); + + 2. Using the following form... + + d = new Drone(self) + + ...will create a new Drone taking the current player as the parameter. If the player's cross-hairs are pointing at a block at the time then, that block's location becomes the drone's starting point. If the cross-hairs are _not_ pointing at a block, then the drone's starting location will be 2 blocks directly in front of the player. TIP: Building always happens right and front of the drone's position... + + Plan View: + + ^ + | + | + D----> + + For convenience you can use a _corner stone_ to begin building. The corner stone should be located just above ground level. If the cross-hair is point at or into ground level when you create a new Drone() with either a player or location given as a parameter, then building begins at the location the player was looking at or at the location. You can get around this by pointing at a 'corner stone' just above ground level or alternatively use the following statement... + + d = new Drone(self).up(); + + ... which will move the drone up one block as soon as it's created. + + ![corner stone](img/cornerstone1.png) + + 3. Or by using the following form... + + d = new Drone(x,y,z,direction,world); + + This will create a new Drone at the location you specified using x, y, z In minecraft, the X axis runs west to east and the Z axis runs north to south. The direction parameter says what direction you want the drone to face: 0 = east, 1 = south, 2 = west, 3 = north. If the direction parameter is omitted, the player's direction is used instead. Both the `direction` and `world` parameters are optional. + + 4. Create a new Drone based on a Location object... + + d = new Drone(location); + + This is useful when you want to create a drone at a given `org.bukkit.Location` . The `Location` class is used throughout the bukkit API. For example, if you want to create a drone when a block is broken at the block's location you would do so like this... + + events.blockBreak( function( event ) { + var location = event.block.location; + var drone = new Drone(location); + // do more stuff with the drone here... + }); + +#### Parameters + + * Player : If a player reference is given as the sole parameter then the block the player was looking at will be used as the starting point for the drone. If the player was not looking at a block then the player's location will be used as the starting point. If a `Player` object is provided as a paramter then it should be the only parameter. + * location : *NB* If a `Location` object is provided as a parameter, then it should be the only parameter. + * x : The x coordinate of the Drone (x,y,z,direction and world are not needed if either a player or location parameter is provided) + * y : The y coordinate of the Drone + * z : The z coordinate of the Drone + * direction : The direction in which the Drone is facing. Possible values are 0 (east), 1 (south), 2 (west) or 3 (north) + * world : The world in which the drone is created. + +### Drone.box() method + +the box() method is a convenience method for building things. (For the more performance-oriented method - see cuboid) + +#### parameters + + * b - the block id - e.g. 6 for an oak sapling or '6:2' for a birch sapling. Alternatively you can use any one of the `blocks` values e.g. `blocks.sapling.birch` + * w (optional - default 1) - the width of the structure + * h (optional - default 1) - the height of the structure + * d (optional - default 1) - the depth of the structure - NB this is not how deep underground the structure lies - this is how far away (depth of field) from the drone the structure will extend. + +#### Example + +To create a black structure 4 blocks wide, 9 blocks tall and 1 block long... + + box(blocks.wool.black, 4, 9, 1); + +... or the following code does the same but creates a variable that can be used for further methods... + + var drone = new Drone(self); + drone.box(blocks.wool.black, 4, 9, 1); + +![box example 1](img/boxex1.png) + +### Drone.box0() method + +Another convenience method - this one creates 4 walls with no floor or ceiling. + +#### Parameters + + * block - the block id - e.g. 6 for an oak sapling or '6:2' for a birch sapling. Alternatively you can use any one of the `blocks` values e.g. `blocks.sapling.birch` + * width (optional - default 1) - the width of the structure + * height (optional - default 1) - the height of the structure + * length (optional - default 1) - the length of the structure - how far + away (depth of field) from the drone the structure will extend. + +#### Example + +To create a stone building with the insided hollowed out 7 wide by 3 tall by 6 long... + + box0( blocks.stone, 7, 3, 6); + +![example box0](img/box0ex1.png) + +### Drone.boxa() method + +Construct a cuboid using an array of blocks. As the drone moves first along the width axis, then the height (y axis) then the length, each block is picked from the array and placed. + +#### Parameters + + * blocks - An array of blocks - each block in the array will be placed in turn. + * width + * height + * length + +#### Example + +Construct a rainbow-colored road 100 blocks long... + + var rainbowColors = [blocks.wool.red, blocks.wool.orange, blocks.wool.yellow, blocks.wool.lime, + blocks.wool.lightblue, blocks.wool.blue, blocks.wool.purple]; + + boxa(rainbowColors,7,1,30); + +![boxa example](img/boxaex1.png) + +### Chaining + +All of the Drone methods return a Drone object, which means methods can be 'chained' together so instead of writing this... + + drone = new Drone( self ); + drone.fwd( 3 ); + drone.left( 2 ); + drone.box( blocks.grass ); // create a grass block + drone.up(); + drone.box( blocks.grass ); // create another grass block + drone.down(); + +...you could simply write ... + + var drone = new Drone(self).fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down(); + +... since each Drone method is also a global function that constructs a drone if none is supplied, you can shorten even further to just... + + fwd(3).left(2).box(blocks.grass).up().box(blocks.grass).down() + +The Drone object uses a [Fluent Interface][fl] to make ScriptCraft scripts more concise and easier to write and read. Minecraft's in-game command prompt is limited to about 80 characters so chaining drone commands together means more can be done before hitting the command prompt limit. For complex building you should save your commands in a new script file and load it using /js load() + +[fl]: http://en.wikipedia.org/wiki/Fluent_interface + +### Drone Properties + + * x - The Drone's position along the west-east axis (x increases as you move east) + * y - The Drone's position along the vertical axis (y increses as you move up) + * z - The Drone's position along the north-south axis (z increases as you move south) + * dir - The Drone's direction 0 is east, 1 is south , 2 is west and 3 is north. + +### Extending Drone + +The Drone object can be easily extended - new buidling recipes/blueprints can be added and can become part of a Drone's chain using the *static* method `Drone.extend`. + +### Drone.extend() static method + +Use this method to add new methods (which also become chainable global functions) to the Drone object. + +#### Parameters + + * name - The name of the new method e.g. 'pyramid'. + * function - The method body. + +Alternatively if you provide just a function as a parameter, then the function name will be used as the new method name. For example the following two approaches are both valid. + +#### Example 1 Using name and function as parameters + + // submitted by [edonaldson][edonaldson] + var Drone = require('drone'); + Drone.extend('pyramid', function( block,height) { + this.chkpt('pyramid'); + for ( var i = height; i > 0; i -= 2) { + this.box(block, i, 1, i).up().right().fwd(); + } + return this.move('pyramid'); + }); + +#### Example 2 Using just a named function as a parameter + + var Drone = require('drone'); + function pyramid( block,height) { + this.chkpt('pyramid'); + for ( var i = height; i > 0; i -= 2) { + this.box(block, i, 1, i).up().right().fwd(); + } + return this.move('pyramid'); + } + Drone.extend( pyramid ); + +Once the method is defined (it can be defined in a new pyramid.js file) it can be used like so... + + var d = new Drone(self); + d.pyramid(blocks.brick.stone, 12); + +... or simply ... + + pyramid(blocks.brick.stone, 12); + +[edonaldson]: https://github.com/edonaldson + +### Drone Constants + +#### Drone.PLAYER_STAIRS_FACING + +An array which can be used when constructing stairs facing in the Drone's direction... + + var d = new Drone(self); + d.box(blocks.stairs.oak + ':' + Drone.PLAYER_STAIRS_FACING[d.dir]); + +... will construct a single oak stair block facing the drone. + +#### Drone.PLAYER_SIGN_FACING + +An array which can be used when placing signs so they face in a given direction. This is used internally by the Drone.sign() method. It should also be used for placing any of the following blocks... + + * chest + * ladder + * furnace + * dispenser + +By default, chests, dispensers, signs, ladders and furnaces are placed facing towards the drone so to place a chest facing the Drone just use: + + drone.box( blocks.chest ); + +To place a chest facing _away_ from the Drone: + + drone.box( blocks.chest + ':' + Drone.PLAYER_SIGN_FACING[(drone.dir + 2) % 4]); + +#### Drone.PLAYER_TORCH_FACING + +Used when placing torches. By default torches will be placed facing up. If you want to place a torch so that it faces towards the drone: + + drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[drone.dir]); + +If you want to place a torch so it faces _away_ from the drone: + + drone.box( blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[(drone.dir + 2) % 4]); + +***/ + +// +// Implementation +// ============== +// +// There is no need to read any further unless you want to understand how the Drone object works. +// +function getDirFromRotation( location ) { + // 0 = east, 1 = south, 2 = west, 3 = north + // 46 to 135 = west + // 136 to 225 = north + // 226 to 315 = east + // 316 to 45 = south + var r; + if (__plugin.canary ) { + r = location.rotation; + } + if (__plugin.bukkit) { + r = location.yaw; + } + + // west = -270 + // north = -180 + // east = -90 + // south = 0 + + r = (r + 360 ) % 360; // east could be 270 or -90 + + if ( r > 45 && r <= 135 ) + return 2; // west + if ( r > 135 && r <= 225 ) + return 3; // north + if ( r > 225 && r <= 315 ) + return 0; // east + return 1; // south +} +/* + low-level function to place a block in the world - all drone methods which + place blocks ultimately invoke this function. +*/ +function putBlock( x, y, z, blockId, metadata, world, update ) { + if ( typeof metadata == 'undefined' ) { + metadata = 0; + } + var block = world.getBlockAt( x, y, z ); + + if (__plugin.canary) { + var BlockType = Packages.net.canarymod.api.world.blocks.BlockType; + block.type = BlockType.fromId(blockId); + var applyProperties = require('blockhelper').applyProperties; + applyProperties(block, metadata); + if (typeof update === 'undefined'){ + update = true; + } + if (update){ + block.update(); + } + } + if (__plugin.bukkit) { + block.setTypeIdAndData( blockId, metadata, false ); + block.data = metadata; + } + return block; +} +/* + Drone constructs a new Drone object +*/ +function Drone( x, y, z, dir, world ) { + this.record = false; + var usePlayerCoords = false; + var player = (typeof self !== 'undefined' ? self : null); + var playerPos; + if ( x.location && x.name) { + player = x; + } + playerPos = x.location; + + var that = this; + var populateFromLocation = function( loc ) { + that.x = loc.x; + that.y = loc.y; + that.z = loc.z; + that.dir = getDirFromRotation(loc); + that.world = loc.world; + }; + var mp = utils.getMousePos( player ); + if ( typeof x == 'undefined' || x.location ) { + if ( mp ) { + populateFromLocation( mp ); + if ( playerPos ) { + this.dir = getDirFromRotation(playerPos); + } + } else { + // base it on the player's current location + usePlayerCoords = true; + // + // it's possible that drone.js could be loaded by a non-playing op + // (from the server console) + // + if ( !playerPos ) { + return null; + } + populateFromLocation( playerPos ); + } + } else { + if ( arguments[0].x && arguments[0].y && arguments[0].z ) { + populateFromLocation( arguments[ 0 ] ); + } else { + this.x = x; + this.y = y; + this.z = z; + if ( typeof dir == 'undefined' ) { + this.dir = getDirFromRotation( playerPos); + } else { + this.dir = dir%4; + } + if ( typeof world == 'undefined' ) { + this.world = playerPos.world; + } else { + this.world = world; + } + } + } + + if ( usePlayerCoords ) { + this.fwd( 3 ); + } + this.chkpt( 'start' ); + this.record = true; + this.history = []; + this.player = player; + return this; +} + +Drone.getDirFromRotation = getDirFromRotation; + +Drone.opsPerSec = 10; +var theQueue = []; +function processQueue(){ + var process, + i = 0, + queues = getAllQueues(); + + for ( ; i < queues.length; i++ ) { + process = queues[i].shift(); + if (process){ + try { + process(); + } catch( e ) { + console.log('Drone build error: ' + e + ' while processing ' + process); + } + } + } + setTimeout( processQueue, 1000 / Drone.opsPerSec ); +}; +setTimeout( processQueue, 1000 / Drone.opsPerSec ); + +addUnloadHandler( function() { + var pendingBuildOps = 0; + var allQueues = getAllQueues(); + for (var i = 0; i < allQueues.length; i++){ + pendingBuildOps += allQueues[i].length; + } + if (pendingBuildOps > 0){ + console.warn('There were ' + pendingBuildOps + ' pending build operations which were cancelled'); + } +}); +// +// add custom methods to the Drone object using this function +// +Drone.extend = function( name, func ) { + if (arguments.length == 1){ + func = name; + if ( !func.name ){ + throw 'A Drone extension function must have a name!'; + } + name = func.name; + } + Drone.prototype[ '_' + name ] = func; + Drone.prototype[ name ] = function( ) { + if ( this.record ) { + this.history.push( [ name, arguments ] ); + } + var oldVal = this.record; + this.record = false; + this[ '_' + name ].apply( this, arguments ); + this.record = oldVal; + return this; + }; + + global[name] = function( ) { + var result = new Drone( self ); + result[name].apply( result, arguments ); + return result; + }; +}; + +/************************************************************************** +### Drone.times() Method + +The `times()` method makes building multiple copies of buildings +easy. It's possible to create rows or grids of buildings without +resorting to `for` or `while` loops. + +#### Parameters + + * numTimes : The number of times you want to repeat the preceding statements. + +#### Limitation + +For now, don't use `times()` inside a Drone method implementation – only use it at the in-game prompt as a short-hand workaround for loops. + +#### Example + +Say you want to do the same thing over and over. You have a couple of options: + + * You can use a `for` loop … + + d = new Drone(); for ( var i = 0; i < 4; i++ ) { d.cottage().right(8); } + +While this will fit on the in-game prompt, it's awkward. You need to +declare a new Drone object first, then write a `for` loop to create the +4 cottages. It's also error prone – even the `for` loop is too much +syntax for what should really be simple. + + * You can use a `while` loop … + + d = new Drone(); var i=4; while (i--) { d.cottage().right(8); } + +… which is slightly shorter but still too much syntax. Each of the +above statements is fine for creating a 1-dimensional array of +structures. But what if you want to create a 2-dimensional or +3-dimensional array of structures? Enter the `times()` method. + +The `times()` method lets you repeat commands in a chain any number of +times. So to create 4 cottages in a row you would use the following +statement: + + cottage().right(8).times(4); + +… which will build a cottage, then move right 8 blocks, then do it +again 4 times over so that at the end you will have 4 cottages in a +row. What's more, the `times()` method can be called more than once in +a chain. So if you wanted to create a *grid* of 20 houses ( 4 x 5 ), +you would do so using the following statement: + + cottage().right(8).times(4).fwd(8).left(32).times(5); + +… breaking it down … + + 1. The first 3 calls in the chain ( `cottage()`, `right(8)`, `times(4)` ) build a single row of 4 cottages. + + 2. The last 3 calls in the chain ( `fwd(8)`, `left(32)`, `times(5)` ) move the drone forward 8 then left 32 blocks (4 x 8) to return to the original X coordinate, then everything in the chain is repeated again 5 times so that in the end, we have a grid of 20 cottages, 4 x 5. Normally this would require a nested loop but the `times()` method does away with the need for loops when repeating builds. + +Another example: This statement creates a row of trees 2 by 3: + + oak().right(10).times(2).left(20).fwd(10).times(3) + +… You can see the results below. + +![times example 1](img/times-trees.png) + +***/ +Drone.prototype.times = function( numTimes, commands ) { + if ( typeof commands == 'undefined' ) { + commands = this.history.concat(); + } + + this.history = [ [ 'times', [ numTimes + 1, commands ] ] ]; + var oldVal = this.record; + this.record = false; + for ( var j = 1; j < numTimes; j++ ) { + for ( var i = 0; i < commands.length; i++) { + var command = commands[i]; + var methodName = command[0]; + var args = command[1]; + this[ methodName ].apply( this, args ); + } + } + this.record = oldVal; + return this; +}; + + +Drone.prototype.getBlock = function(){ + return this.world.getBlockAt(this.x,this.y,this.z); +}; +Drone.prototype.setBlock = function(blockType, data, ow, oh, od, update){ + if (typeof ow == 'undefined') + ow = 0; + if (typeof oh == 'undefined') + oh = 0; + if (typeof od == 'undefined') + od = 0; + this + .right(ow) + .up(oh) + .fwd(od); + var result = putBlock(this.x, this.y, this.z, blockType, data, this.world, update); + this + .left(ow) + .down(oh) + .back(od); + return result; +}; +Drone.prototype.traverseWidth = function(width, callback){ + _traverse[this.dir].width(this, width, callback); +}; +Drone.prototype.traverseHeight = function(height, callback){ + traverseHeight(this, height, callback); +}; +Drone.prototype.traverseDepth = function(depth, callback){ + _traverse[this.dir].depth(this, depth, callback); +}; +// +// building +// + +var playerQueues = {}; +/* + if the drone has an associated player, then use that player's queue otherwise + use the global queue. +*/ +function getQueue( drone ){ + if ( drone.player ) { + var playerName = ''+drone.player.name; + var result = playerQueues[playerName]; + if (result === undefined){ + playerQueues[playerName] = []; + return playerQueues[playerName]; + } + return result; + } else { + return theQueue; + } +} +function getAllQueues() { + var result = [ theQueue ]; + for (var pq in playerQueues) { + result.push(playerQueues[pq]) ; + } + return result; +} +Drone.prototype.cuboida = function(/* Array */ blocks, w, h, d, overwrite) { + if ( typeof overwrite == 'undefined' ) { + overwrite = true; + } + if ( typeof h == 'undefined' ) { + h = 1; + } + if ( typeof d == 'undefined' ) { + d = 1; + } + if ( typeof w == 'undefined' ) { + w = 1; + } + // + // wph 20140823 make a copy because don't want to modify array in background + // + var blocksForBuild = blocks.slice(); + var len = blocksForBuild.length, + i = 0; + for ( ; i < len; i++ ) { + blocksForBuild[i] = this.getBlockIdAndMeta( blocksForBuild[ i ] ); + } + this.then(function(){ + var bi = 0; + traverseDHW( this, d,h,w, function traverseWidthCallback( ) { + var properBlock = blocksForBuild[ bi % len ]; + this.setBlock(properBlock[0], properBlock[1]); + bi++; + }); + }); + return this; +}; +Drone.MAX_VOLUME = 1 * MILLION; +Drone.MAX_SIDE = 1 * THOUSAND; + +var tooBig = function(w, h, d ) { + return ( w * h * d ) >= Drone.MAX_VOLUME || + ( w >= Drone.MAX_SIDE ) || + ( h >= Drone.MAX_SIDE ) || + ( d >= Drone.MAX_SIDE ); +}; +/* + faster cuboid because blockid, meta and world must be provided + use this method when you need to repeatedly place blocks + */ +Drone.prototype.cuboidX = function( blockType, meta, w, h, d, immediate ) { + + if ( typeof h == 'undefined' ) { + h = 1; + } + if ( typeof d == 'undefined' ) { + d = 1; + } + if ( typeof w == 'undefined' ) { + w = 1; + } + if ( tooBig( w, h, d ) ) { + this.sign([ + 'Build too Big!', + 'width:' + w, + 'height:' + h, + 'depth:' + d + ], 68); + console.warn('Build too big! ' + w + ' X ' + h + ' X ' + d); + return this; + } + if ( !immediate ) { + this.then(function(){ + traverseDHW( this, d,h,w, function( ) { + this.setBlock( blockType, meta ); + }); + }); + } else { + traverseDHW( this, d,h,w, function( ) { + this.setBlock( blockType, meta ); + }); + } + return this; + +}; +/* + deferred execution of a drone method +*/ +var thenID = 0; +Drone.prototype.then = function( next ){ + var chkptThen = '_now' + (thenID++); + this.chkpt(chkptThen); + var thisNext = next.bind(this); + function wrapperFn(){ + var chkNow = '_now' + (thenID++); + this.chkpt(chkNow); + this.move(chkptThen); + thisNext(); + this.move(chkNow); + } + getQueue(this).push( wrapperFn.bind(this) ); + return this; +}; +Drone.prototype.cuboid = function( block, w, h, d, immediate ) { + var bm = this.getBlockIdAndMeta( block ); + return this.cuboidX( bm[0], bm[1], w, h, d, immediate); +}; + +Drone.prototype.cuboid0 = function( block, w, h, d, immediate ) { + var start = 'cuboid0' + w + h + d + immediate; + this + .chkpt( start ) + .cuboid( block, w, h, 1, immediate ) // Front wall + .cuboid( block, 1, h, d, immediate ) // Left wall + .right( w - 1 ) + .cuboid( block, 1, h, d, immediate ) // Right wall + .left( w - 1 ) + .fwd( d - 1 ) + .cuboid( block, w, h, 1, immediate ) // Back wall + .move( start ); +}; + + + +// player dirs: 0 = east, 1 = south, 2 = west, 3 = north +// block dirs: 0 = east, 1 = west, 2 = south , 3 = north +// sign dirs: 5 = east, 3 = south, 4 = west, 2 = north +Drone.PLAYER_STAIRS_FACING = [ 0, 2, 1, 3 ]; + +// for blocks 68 (wall signs) 65 (ladders) 61,62 (furnaces) 23 (dispenser) and 54 (chest) +Drone.PLAYER_SIGN_FACING = [ 4, 2, 5, 3 ]; +Drone.PLAYER_TORCH_FACING = [ 2, 4, 1, 3 ]; + +Drone.extend('box', Drone.prototype.cuboid ); +Drone.extend('box0',Drone.prototype.cuboid0 ); +Drone.extend('boxa',Drone.prototype.cuboida ); +// +// show the Drone's position and direction +// +Drone.prototype.toString = function( ) { + var dirs = ['east','south','west','north']; + return 'x: ' + this.x + ' y: '+this.y + ' z: ' + this.z + ' dir: ' + this.dir + ' '+dirs[this.dir]; +}; +Drone.prototype.debug = function( ) { + console.log(this.toString( ) ); + return this; +}; + +function getBlockIdAndMeta( b ) { + var defaultMeta = 0, + i = 0, + bs, + md, + sp; + if (typeof b === 'number' || /^[0-9]+$/.test(b)) { + // wph 20130414 - use sensible defaults for certain blocks e.g. stairs + // should face the drone. + switch (b) { + case blocks.stairs.oak: + case blocks.stairs.cobblestone: + case blocks.stairs.brick: + case blocks.stairs.stone: + case blocks.stairs.nether: + case blocks.stairs.sandstone: + case blocks.stairs.spruce: + case blocks.stairs.jungle: + case blocks.stairs.quartz: + defaultMeta = Drone.PLAYER_STAIRS_FACING[ this.dir % 4 ]; + break; + case blocks.sign: + case blocks.ladder: + // bug: furnace, chest, dispenser don't always use the right metadata + case blocks.furnace: + case blocks.furnace_burning: + case blocks.chest: + case blocks.enderchest: + case blocks.dispenser: + defaultMeta = Drone.PLAYER_SIGN_FACING[ this.dir % 4 ]; + break; + case blocks.sign_post: + defaultMeta = ( 12 + ( ( this.dir + 2 ) * 4 ) ) % 16; + break; + } + return [ b, defaultMeta ]; + } + if ( typeof b === 'string' ) { + bs = b; + sp = bs.indexOf(':' ); + if ( sp == -1 ) { + b = parseInt( bs ); + return [ b, defaultMeta ]; + } + b = parseInt(bs.substring(0,sp ) ); + md = parseInt(bs.substring(sp+1,bs.length ) ); + return [b,md]; + } + if (b.id){ + // wph 20141230 we are dealing with an object + var blockInfo = b; + var metadata = {}; + for (i in b){ + if (i !== 'id') + metadata[i] = b[i]; + } + return [b.id, metadata]; + } +} +var _traverse = [{},{},{},{}]; +// east +function walkWidthEast( drone, n,callback ) { + var s = drone.z, e = s + n; + for ( ; drone.z < e; drone.z++ ) { + callback.call(drone ,drone.z-s ); + } + drone.z = s; +} +function walkDepthEast( drone,n,callback ) { + var s = drone.x, e = s+n; + for ( ;drone.x < e;drone.x++ ) { + callback.call(drone, drone.x-s ); + } + drone.x = s; +} +function walkWidthSouth( drone,n,callback ) { + var s = drone.x, e = s-n; + for ( ;drone.x > e;drone.x-- ) { + callback.call(drone, s-drone.x ); + } + drone.x = s; +} +function walkWidthWest( drone,n,callback ) { + var s = drone.z, e = s-n; + for ( ;drone.z > e;drone.z-- ) { + callback.call(drone, s-drone.z ); + } + drone.z = s; +} +_traverse[0].width = walkWidthEast; +_traverse[0].depth = walkDepthEast; +// south +_traverse[1].width = walkWidthSouth; +_traverse[1].depth = walkWidthEast; +// west +_traverse[2].width = walkWidthWest; +_traverse[2].depth = walkWidthSouth; +// north +_traverse[3].width = walkDepthEast; +_traverse[3].depth = walkWidthWest; +function traverseHeight( drone,n,callback ) { + var s = drone.y, e = s + n; + for ( ; drone.y < e; drone.y++ ) { + callback.call(drone, drone.y-s ); + } + drone.y = s; +}; +function traverseDHW( drone, d,h,w, callback ){ + _traverse[drone.dir].depth( drone, d, function traverseDepthCallback( ) { + traverseHeight( this, h, function traverseHeightCallback( ) { + _traverse[this.dir].width( this, w, callback); + }); + }); +} + +// +// wph 20130130 - make this a method - extensions can use it. +// +Drone.prototype.getBlockIdAndMeta = getBlockIdAndMeta; +Drone.prototype._getBlockIdAndMeta = function(b){ + console.warn('_getBlockIdAndMeta is deprecated. Use .getBlockIdAndMeta() instead'); + return this.getBlockIdAndMeta(b); +}; +Drone.bountiful = __plugin.canary ? parseFloat(server.canaryModVersion) > 1.7 : false; + +var droneCoreExts = [ + './arc', + './bed', + './blocktype', + './copypaste', + './cylinders', + './doors', + './firework', + './garden', + './ladder', + './movement', + './prism', + './rand', + './sign', + './sphere', + './stairs', + './trees' +]; +utils.foreach(droneCoreExts, function(path){ + require(path)(Drone); +}); +module.exports = Drone; diff --git a/server/scriptcraft/modules/drone/ladder.js b/server/scriptcraft/modules/drone/ladder.js new file mode 100755 index 0000000..312648a --- /dev/null +++ b/server/scriptcraft/modules/drone/ladder.js @@ -0,0 +1,46 @@ +'use strict'; +/*global require, module*/ +/************************************************************************ +### Drone.ladder() method + +Creates a ladder extending skyward. + +#### Parameters + + * height (optional - default 1) + +#### Example + +To create a ladder extending 10 blocks high: + + var drone = new Drone(self); + drone.ladder(10) + +At the in-game prompt, look at a block and then type: + + /js ladder(10) + +A ladder 10 blocks high will be created at the point you were looking at. + +#### Since +##### 3.0.3 +***/ +var blocks = require('blocks'); + +function ladder( height ){ + this.then(function ladderLater(){ + var block = this.getBlock(); + if (block.typeId == blocks.air || block.typeId == blocks.ladder){ + this.box(blocks.ladder, 1, height, 1, true); + } else { + this + .back() + .box(blocks.ladder, 1, height, 1, true) + .fwd(); + } + }); +} + +module.exports = function(Drone){ + Drone.extend( ladder ); +}; diff --git a/server/scriptcraft/modules/drone/movement.js b/server/scriptcraft/modules/drone/movement.js new file mode 100755 index 0000000..2d63d4a --- /dev/null +++ b/server/scriptcraft/modules/drone/movement.js @@ -0,0 +1,189 @@ +'use strict'; +/*global require,__plugin, module, Packages, org*/ + +/************************************************************************ +### Drone Movement + +Drones can move freely in minecraft's 3-D world. You control the +Drone's movement using any of the following methods.. + + * up() + * down() + * left() + * right() + * fwd() + * back() + * turn() + +... Each of these methods takes a single optional parameter +`numBlocks` - the number of blocks to move in the given direction. If +no parameter is given, the default is 1. + +To change direction use the `turn()` method which also takes a single +optional parameter (numTurns) - the number of 90 degree turns to +make. Turns are always clock-wise. If the drone is facing north, then +drone.turn() will make the turn face east. If the drone is facing east +then drone.turn(2) will make the drone turn twice so that it is facing +west. + +### Drone Positional Info + + * getLocation() - Returns a native Java Location object for the drone + +### Drone Markers + +Markers are useful when your Drone has to do a lot of work. You can +set a check-point and return to the check-point using the move() +method. If your drone is about to undertake a lot of work - +e.g. building a road, skyscraper or forest you should set a +check-point before doing so if you want your drone to return to its +current location. + +A 'start' checkpoint is automatically created when the Drone is first created. + +Markers are created and returned to using the followng two methods... + + * chkpt - Saves the drone's current location so it can be returned to later. + * move - moves the drone to a saved location. Alternatively you can provide a Java Location object or x,y,z and direction parameters. + +#### Parameters + + * name - the name of the checkpoint to save or return to. + +#### Example + + drone.chkpt('town-square'); + // + // the drone can now go off on a long excursion + // + for ( i = 0; i< 100; i++) { + drone.fwd(12).box(6); + } + // + // return to the point before the excursion + // + drone.move('town-square'); + +***/ +var _movements = [{},{},{},{}]; +// east +_movements[0].right = function( drone,n ) { drone.z +=n; return drone;}; +_movements[0].left = function( drone,n ) { drone.z -=n; return drone;}; +_movements[0].fwd = function( drone,n ) { drone.x +=n; return drone;}; +_movements[0].back = function( drone,n ) { drone.x -= n; return drone;}; +// south +_movements[1].right = _movements[0].back; +_movements[1].left = _movements[0].fwd; +_movements[1].fwd = _movements[0].right; +_movements[1].back = _movements[0].left; +// west +_movements[2].right = _movements[0].left; +_movements[2].left = _movements[0].right; +_movements[2].fwd = _movements[0].back; +_movements[2].back = _movements[0].fwd; +// north +_movements[3].right = _movements[0].fwd; +_movements[3].left = _movements[0].back; +_movements[3].fwd = _movements[0].left; +_movements[3].back = _movements[0].right; + +function turn( n ) { + if ( typeof n == 'undefined' ) { + n = 1; + } + this.dir += n; + this.dir %=4; +} +function chkpt( name ) { + this._checkpoints[ name ] = { x:this.x, y:this.y, z:this.z, dir:this.dir }; +} +function move( ) { + var Drone = this.constructor; + if ( arguments[0].x && arguments[0].y && arguments[0].z) { + this.x = arguments[0].x; + this.y = arguments[0].y; + this.z = arguments[0].z; + this.dir = Drone.getDirFromRotation(arguments[0] ); + this.world = arguments[0].world; + } else if ( typeof arguments[0] === 'string' ) { + var coords = this._checkpoints[arguments[0]]; + if ( coords ) { + this.x = coords.x; + this.y = coords.y; + this.z = coords.z; + this.dir = coords.dir%4; + } + } else { + // expect x,y,z,dir + switch( arguments.length ) { + case 4: + this.dir = arguments[3]; + case 3: + this.z = arguments[2]; + case 2: + this.y = arguments[1]; + case 1: + this.x = arguments[0]; + } + } +} +function right( n ) { + if ( typeof n == 'undefined' ) { + n = 1; + } + _movements[ this.dir ].right( this, n ); +} +function left( n ) { + if ( typeof n == 'undefined') { + n = 1; + } + _movements[ this.dir ].left( this, n ); +} +function fwd( n ) { + if ( typeof n == 'undefined' ) { + n = 1; + } + _movements[ this.dir ].fwd( this, n ); +} +function back( n ) { + if ( typeof n == 'undefined' ) { + n = 1; + } + _movements[ this.dir ].back( this, n ); +} +function up( n ) { + if ( typeof n == 'undefined' ) { + n = 1; + } + this.y+= n; +} +function down( n ) { + if ( typeof n == 'undefined' ) { + n = 1; + } + this.y-= n; +} +function getLocation( ) { + if (__plugin.canary) { + var cmLocation = Packages.net.canarymod.api.world.position.Location; + return new cmLocation( this.world, this.x, this.y, this.z, 0, 0); + } + if (__plugin.bukkit) { + var bkLocation = org.bukkit.Location; + return new bkLocation( this.world, this.x, this.y, this.z ); + } +} +module.exports = function(Drone){ + Drone.prototype._checkpoints = {}; + Drone.prototype.getLocation = getLocation; + Drone.extend( chkpt ); + Drone.extend( move ); + Drone.extend( turn ); + Drone.extend( right ); + Drone.extend( left ); + Drone.extend( fwd ); + Drone.extend( back ); + Drone.extend( up ); + Drone.extend( down ); +}; + diff --git a/server/scriptcraft/modules/drone/prism.js b/server/scriptcraft/modules/drone/prism.js new file mode 100755 index 0000000..1096514 --- /dev/null +++ b/server/scriptcraft/modules/drone/prism.js @@ -0,0 +1,98 @@ +'use strict'; +/*global require, module*/ +/************************************************************************ +### Drone.prism() method + +Creates a prism. This is useful for roofs on houses. + +#### Parameters + + * block - the block id - e.g. 6 for an oak sapling or '6:2' for a birch sapling. + Alternatively you can use any one of the `blocks` values e.g. `blocks.sapling.birch` + * width - the width of the prism + * length - the length of the prism (will be 2 time its height) + +#### Example + + prism(blocks.oak,3,12); + +![prism example](img/prismex1.png) + +### Drone.prism0() method + +A variation on `prism` which hollows out the inside of the prism. It +uses the same parameters as `prism`. + +***/ +var STAIRBLOCKS = { + 53: '5:0' // oak wood + ,67: 4 // cobblestone + ,108: 45 // brick + ,109: 98 // stone brick + ,114: 112 // nether brick + ,128: 24 // sandstone + ,134: '5:1' // spruce wood + ,135: '5:2' // birch wood + ,136: '5:3' // jungle wood + ,156: 155 // quartz +}; +// +// prism private implementation +// +function prism( block, w, d ) { + var stairEquiv = STAIRBLOCKS[block]; + if ( stairEquiv ) { + this + .fwd() + .prism( stairEquiv,w,d-2 ) + .back() + .stairs(block, w, d / 2) + .fwd(d - 1) + .right(w - 1) + .turn(2) + .stairs(block, w, d / 2) + .turn(2) + .left(w - 1) + .back(d - 1); + }else{ + var c = 0; + var d2 = d; + while ( d2 >= 1 ) { + this.cuboid(block,w,1,d2 ); + d2 -= 2; + this.fwd( ).up( ); + c++; + } + this.down(c ).back(c ); + } + return this; +}; +// +// prism0 private implementation +// +function prism0( block,w,d ) { + this + .stairs(block,w,d/2) + .fwd(d-1) + .right(w-1) + .turn(2) + .stairs(block,w,d/2) + .turn(2) + .left(w-1) + .back(d-1); + + var se = STAIRBLOCKS[block]; + if (se) { + this + .fwd() + .prism(se,1,d-2) + .right(w-1) + .prism(se,1,d-2) + .left(w-1) + .back(); + } +} +module.exports = function(Drone){ + Drone.extend(prism0); + Drone.extend(prism); +}; diff --git a/server/scriptcraft/modules/drone/rand.js b/server/scriptcraft/modules/drone/rand.js new file mode 100755 index 0000000..8a7ec1a --- /dev/null +++ b/server/scriptcraft/modules/drone/rand.js @@ -0,0 +1,67 @@ +'use strict'; +/*global require, module*/ +/************************************************************************ +### Drone.rand() method + +rand takes either an array (if each blockid has the same chance of occurring) or an object where each property is a blockid and the value is it's weight (an integer) + +#### Example + +place random blocks stone, mossy stone and cracked stone (each block has the same chance of being picked) + + rand( [blocks.brick.stone, blocks.brick.mossy, blocks.brick.cracked ],w,d,h) + +to place random blocks stone has a 50% chance of being picked, + + var distribution = {}; + distribution[ blocks.brick.stone ] = 5; + distribution[ blocks.brick.mossy ] = 3; + distribution[ blocks.brick.cracked ] = 2; + + rand( distribution, width, height, depth) + +regular stone has a 50% chance, mossy stone has a 30% chance and cracked stone has just a 20% chance of being picked. + +***/ +// +// standard fisher-yates shuffle algorithm +// +function fisherYates( myArray ) { + var i = myArray.length; + if ( i == 0 ) return false; + while ( --i ) { + var j = Math.floor( Math.random( ) * ( i + 1 ) ); + var tempi = myArray[i]; + var tempj = myArray[j]; + myArray[i] = tempj; + myArray[j] = tempi; + } +} +function _rand( blockDistribution ) { + if ( !(blockDistribution.constructor == Array ) ) { + var a = []; + for ( var p in blockDistribution ) { + var n = blockDistribution[p]; + for ( var i = 0;i < n;i++ ) { + a.push(p ); + } + } + blockDistribution = a; + } + while ( blockDistribution.length < 1000 ) { + // make array bigger so that it's more random + blockDistribution = blockDistribution.concat(blockDistribution ); + } + fisherYates(blockDistribution ); + return blockDistribution; +} +function rand( dist, width, height, depth, overwrite ) { + if ( typeof overwrite == 'undefined' ) { + overwrite = true; + } + var randomized = _rand( dist ); + this.boxa( randomized, width, height, depth, overwrite); +} +module.exports = function(Drone){ + Drone.extend( rand ); +}; diff --git a/server/scriptcraft/modules/drone/sign.js b/server/scriptcraft/modules/drone/sign.js new file mode 100755 index 0000000..8d84a7f --- /dev/null +++ b/server/scriptcraft/modules/drone/sign.js @@ -0,0 +1,144 @@ +'use strict'; +/*global require, echo,__plugin, module*/ +var blocks = require('blocks'); +/************************************************************************ +### Drone.wallsign() method + +Creates a wall sign (A sign attached to a wall) + +#### Parameters + + * message - can be a string or an array of strings + +#### Example + + drone.wallsign(['Welcome','to','Scriptopia']); + +![wall sign](img/signex2.png) + +### Drone.signpost() method + +Creates a free-standing signpost + +#### Parameters + + * message - can be a string or an array of strings + +#### Example + + drone.signpost(['Hello','World']); + +![ground sign](img/signex1.png) + +### Drone.sign() method + +Deprecated: Use signpost() or wallsign() methods instead. + +Signs must use block 63 (stand-alone signs) or 68 (signs on walls) + +#### Parameters + + * message - can be a string or an array of strings. + * block - can be 63 or 68 + +#### Example + +To create a free-standing sign... + + drone.sign(["Hello","World"], blocks.sign_post); + +![ground sign](img/signex1.png) + +... to create a wall mounted sign... + + drone.sign(["Welcome","to","Scriptopia"], blocks.sign ); + +![wall sign](img/signex2.png) + +***/ +function putSign( drone, texts, blockId, meta ) { + var i, + len = texts.length, + block, + state, + getState, + isSign, + setLine; + + if ( blockId != blocks.sign_post && blockId != blocks.sign ) { + throw new Error( 'Invalid Parameter: blockId must be blocks.sign_post or blocks.sign' ); + } + block = drone.setBlock( blockId, meta); + if (__plugin.canary){ + isSign = function(block){ + var sign = block.getTileEntity(); + return sign.setTextOnLine; + }; + setLine = function( block, i) { + var sign = block.getTileEntity(); + sign.setTextOnLine( texts[i], i ); + sign.update(); + }; + } + if (__plugin.bukkit){ + isSign = function(block){ return block.state && block.state.setLine; }; + setLine = function( block, i) { + var sign = block.state; + sign.setLine( i, texts[i] ); + sign.update(true); + }; + } + if ( isSign(block) ) { + if (len > 4){ + len = 4; + } + for ( i = 0; i < len; i++ ) { + setLine(block, i, texts[ i ] ); + } + } +}; +function signpost( message ){ + this.then(function(){ + this.sign(message, blocks.sign_post); + }); +} +function wallsign( message ){ + /* + must allow for /js wallsign() while looking at a wall block + */ + this.then(function(){ + var block = this.getBlock(); + if (block.typeId == blocks.air || block.typeId == blocks.sign){ + this.sign(message, blocks.sign); + } else { + this + .back() + .sign(message, blocks.sign) + .fwd(); + } +}); + +} +function sign( message, block ) { + if ( message.constructor != Array ) { + message = [message]; + } + var bm = this.getBlockIdAndMeta( block ); + block = bm[0]; + var meta = bm[1]; + if ( block !== blocks.sign_post && block !== blocks.sign ) { + var usage = 'Usage: sign("message", blocks.sign_post) or sign("message", blocks.sign)'; + if ( this.player ) { + echo( this.player, usage); + } + console.error(usage); + return; + } + putSign( this, message, block, meta); + +} +module.exports = function(Drone){ + Drone.extend(sign); + Drone.extend(signpost); + Drone.extend(wallsign); +}; diff --git a/server/scriptcraft/modules/drone/sphere.js b/server/scriptcraft/modules/drone/sphere.js new file mode 100755 index 0000000..c805654 --- /dev/null +++ b/server/scriptcraft/modules/drone/sphere.js @@ -0,0 +1,396 @@ +'use strict'; +/*global module*/ +/************************************************************************ +### Drone.sphere() method + +Creates a sphere. + +#### Parameters + + * block - The block the sphere will be made of. + * radius - The radius of the sphere. + +#### Example + +To create a sphere of Iron with a radius of 10 blocks... + + sphere( blocks.iron, 10); + +![sphere example](img/sphereex1.png) + +Spheres are time-consuming to make. You *can* make large spheres (250 radius) but expect the +server to be very busy for a couple of minutes while doing so. + +***/ +function sphere( block, radius ) { + var lastRadius = radius, + slices = [ [ radius , 0 ] ], + diameter = radius * 2, + bm = this.getBlockIdAndMeta( block ), + r2 = radius * radius, + i = 0, + newRadius, + yOffset, + sr, + sh, + v, + h; + + if ( radius > 127 ) { + throw new Error('Sphere radius must be less than 128 blocks'); + } + for ( i = 0; i <= radius; i++ ) { + newRadius = Math.round( Math.sqrt( r2 - i * i ) ); + if ( newRadius == lastRadius ) { + slices[ slices.length - 1 ][ 1 ]++; + } else { + slices.push( [ newRadius , 1 ] ); + } + lastRadius = newRadius; + } + this.chkpt( 'sphere' ); + // + // mid section + // + this.up( radius - slices[0][1] ) + .cylinder( block, radius, ( slices[0][1]*2 ) - 1, { blockType: bm[0], meta: bm[1] } ) + .down( radius - slices[0][1] ); + + yOffset = -1; + for ( i = 1; i < slices.length; i++ ) { + yOffset += slices[i-1][1]; + sr = slices[i][0]; + sh = slices[i][1]; + v = radius + yOffset; + h = radius - sr; + // northern hemisphere + this.up( v ) + .fwd( h ) + .right( h ) + .cylinder( block, sr, sh, { blockType: bm[0], meta: bm[1] } ) + .left( h ) + .back( h ) + .down( v ); + + // southern hemisphere + v = radius - ( yOffset + sh + 1 ); + this.up( v ) + .fwd( h ) + .right( h ) + .cylinder( block, sr, sh, { blockType: bm[0], meta: bm[1]} ) + .left( h ) + .back( h ) + .down( v ); + } + return this.move( 'sphere' ); +} +/************************************************************************ +### Drone.sphere0() method + +Creates an empty sphere. + +#### Parameters + + * block - The block the sphere will be made of. + * radius - The radius of the sphere. + +#### Example + +To create a sphere of Iron with a radius of 10 blocks... + + sphere0( blocks.iron, 10); + +Spheres are time-consuming to make. You *can* make large spheres (250 radius) but expect the +server to be very busy for a couple of minutes while doing so. + +***/ +function sphere0(block,radius) +{ + var lastRadius = radius, + slices = [ [ radius, 0 ] ], + diameter = radius * 2, + bm = this.getBlockIdAndMeta( block ), + r2 = radius*radius, + i, + newRadius, + sr, + sh, + v, + h, + len, + yOffset; + + if ( radius > 127 ) { + throw new Error('Sphere radius must be less than 128 blocks'); + } + + for ( i = 0; i <= radius; i++ ) { + newRadius = Math.round( Math.sqrt( r2 - i * i ) ); + if ( newRadius == lastRadius ) { + slices[ slices.length - 1 ][ 1 ]++; + } else { + slices.push( [ newRadius, 1 ] ); + } + lastRadius = newRadius; + } + this.chkpt( 'sphere0' ); + // + // mid section + // + this.up( radius - slices[0][1] ) + .arc({ blockType: bm[0], + meta: bm[1], + radius: radius, + strokeWidth: 2, + stack: (slices[0][1]*2)-1, + fill: false + }) + .down( radius - slices[0][1] ); + + yOffset = -1; + len = slices.length; + for ( i = 1; i < len; i++ ) { + yOffset += slices[i-1][1]; + sr = slices[i][0]; + sh = slices[i][1]; + v = radius + yOffset; + h = radius-sr; + // northern hemisphere + // .cylinder(block,sr,sh,{blockType: bm[0],meta: bm[1]}) + this.up( v ).fwd( h ).right( h ) + .arc({ + blockType: bm[0], + meta: bm[1], + radius: sr, + stack: sh, + fill: false, + strokeWidth: i < len - 1 ? 1 + ( sr - slices[ i + 1 ][ 0 ] ) : 1 + }) + .left( h ).back( h ).down( v ); + + // southern hemisphere + v = radius - ( yOffset + sh + 1 ); + this.up( v ).fwd( h ).right( h ) + .arc({ + blockType: bm[0], + meta: bm[1], + radius: sr, + stack: sh, + fill: false, + strokeWidth: i < len - 1 ? 1 + ( sr - slices[ i + 1 ][ 0 ] ) : 1 + }) + .left( h ).back( h ). down( v ); + } + this.move( 'sphere0' ); + + return this; + +} +/************************************************************************ +### Drone.hemisphere() method + +Creates a hemisphere. Hemispheres can be either north or south. + +#### Parameters + + * block - the block the hemisphere will be made of. + * radius - the radius of the hemisphere + * northSouth - whether the hemisphere is 'north' or 'south' + +#### Example + +To create a wood 'north' hemisphere with a radius of 7 blocks... + + hemisphere(blocks.oak, 7, 'north'); + +![hemisphere example](img/hemisphereex1.png) + +***/ +function hemisphere( block, radius, northSouth ) { + var lastRadius = radius, + slices = [ [ radius, 0 ] ], + diameter = radius * 2, + bm = this.getBlockIdAndMeta(block), + r2 = radius * radius, + i = 0, + newRadius; + + if ( radius > 255 ) { + throw new Error('Hemisphere radius must be less than 256 blocks'); + } + + for ( i = 0; i <= radius; i++ ) { + newRadius = Math.round( Math.sqrt( r2 - i * i ) ); + if ( newRadius == lastRadius ) { + slices[ slices.length - 1 ][ 1 ]++; + } else { + slices.push( [ newRadius, 1 ] ); + } + lastRadius = newRadius; + } + this.chkpt( 'hsphere' ); + // + // mid section + // + if ( northSouth == 'north' ) { + this.cylinder( block, radius, slices[0][1], { blockType: bm[0], meta: bm[1] } ); + } else { + this.up( radius - slices[0][1] ) + .cylinder( block, radius, slices[0][1], { blockType: bm[0], meta: bm[1] } ) + .down( radius - slices[0][1] ); + } + + var yOffset = -1; + for ( i = 1; i < slices.length; i++ ) { + yOffset += slices[i-1][1]; + var sr = slices[i][0]; + var sh = slices[i][1]; + var v = yOffset, h = radius-sr; + if ( northSouth == 'north' ) { + // northern hemisphere + this.up( v ).fwd( h ).right( h ) + .cylinder( block, sr, sh, { blockType: bm[0], meta: bm[1] } ) + .left( h ).back( h ).down( v ); + } else { + // southern hemisphere + v = radius - ( yOffset + sh + 1 ); + this.up( v ).fwd( h ).right( h ) + .cylinder( block, sr, sh, { blockType: bm[0], meta: bm[1] } ) + .left( h ).back( h ).down( v ); + } + } + return this.move( 'hsphere' ); +} +/************************************************************************ +### Drone.hemisphere0() method + +Creates a hollow hemisphere. Hemispheres can be either north or south. + +#### Parameters + + * block - the block the hemisphere will be made of. + * radius - the radius of the hemisphere + * northSouth - whether the hemisphere is 'north' or 'south' + +#### Example + +To create a glass 'north' hemisphere with a radius of 20 blocks... + + hemisphere0(blocks.glass, 20, 'north'); + +![hemisphere example](img/hemisphereex2.png) + +***/ +function hemisphere0( block, radius, northSouth ) { + + if ( radius > 255 ) { + throw new Error('Hemisphere radius must be less than 256 blocks'); + } + + var lastRadius = radius, + slices = [ [ radius, 0 ] ], + diameter = radius * 2, + bm = this.getBlockIdAndMeta(block), + r2 = radius * radius, + i = 0, + len, + newRadius; + + if ( radius > 255 ) { + throw new Error('Hemisphere radius must be less than 256 blocks'); + } + + + for ( i = 0; i <= radius; i++ ) { + newRadius = Math.round( Math.sqrt( r2 - i * i ) ); + if ( newRadius == lastRadius ) { + slices[ slices.length - 1 ][ 1 ]++; + } else { + slices.push( [ newRadius, 1 ] ); + } + lastRadius = newRadius; + } + this.chkpt( 'hsphere0' ); + // + // mid section + // + if ( northSouth == 'north' ) { + + this.arc({ + blockType: bm[0], + meta: bm[1], + radius: radius, + strokeWidth: 1, + stack: slices[0][1], + fill: false + }); + } else { + this.up( radius - slices[0][1] ); + + this.arc({ + blockType: bm[0], + meta: bm[1], + radius: radius, + strokeWidth: 1, + stack: slices[0][1], + fill: false + }); + + this.down( radius - slices[0][1] ); + } + + var yOffset = -1; + len = slices.length; + for ( i = 1; i < slices.length; i++ ) { + yOffset += slices[i-1][1]; + var sr = slices[i][0]; + var sh = slices[i][1]; + var v = yOffset, h = radius-sr; + if ( northSouth == 'north' ) { + // northern hemisphere + this.up( v ) + .fwd( h ) + .right( h ); + + this.arc( { + blockType: bm[0], + meta: bm[1], + radius: sr, + stack: sh, + fill: false, + strokeWidth: i < len - 1 ? 1 + ( sr - slices[ i + 1 ][ 0 ] ) : 1 + } ); + + this.left( h ) + .back( h ) + .down( v ); + } else { + // southern hemisphere + v = radius - ( yOffset + sh + 1 ); + this.up( v ) + .fwd( h ) + .right( h ); + + this.arc({ + blockType: bm[0], + meta: bm[1], + radius: sr, + stack: sh, + fill: false, + strokeWidth: i < len - 1 ? 1 + ( sr - slices[ i + 1 ][ 0 ] ) : 1 + }); + + this.left( h ) + .back( h ) + .down( v ); + } + } + return this.move( 'hsphere0' ); + +} +module.exports = function(Drone){ + Drone.extend( sphere ); + Drone.extend( sphere0 ); + Drone.extend( hemisphere ); + Drone.extend( hemisphere0 ); +}; diff --git a/server/scriptcraft/modules/drone/stairs.js b/server/scriptcraft/modules/drone/stairs.js new file mode 100755 index 0000000..519ee1e --- /dev/null +++ b/server/scriptcraft/modules/drone/stairs.js @@ -0,0 +1,61 @@ +'use strict'; +/*global module*/ +/************************************************************************** +### Drone.stairs() function + +The stairs() function will build a flight of stairs + +#### Parameters + + * blockType - should be one of the following: + + * blocks.stairs.oak + * blocks.stairs.cobblestone + * blocks.stairs.brick + * blocks.stairs.stone + * blocks.stairs.nether + * blocks.stairs.sandstone + * blocks.stairs.spruce + * blocks.stairs.birch + * blocks.stairs.jungle + * blocks.stairs.quartz + + * width - The width of the staircase - default is 1 + * height - The height of the staircase - default is 1 + +#### Example + +To build an oak staircase 3 blocks wide and 5 blocks tall: + + /js stairs(blocks.stairs.oak, 3, 5) + +Staircases do not have any blocks beneath them. + +***/ +var blocks = require('blocks'); +/*global require*/ +function stairs(blockType, width, height){ + if (typeof width === 'undefined') + width = 1; + if (typeof height === 'undefined') + height = 1; + if (typeof blockType === 'undefined'){ + blockType = blocks.stairs.oak; + } + var bm = this.getBlockIdAndMeta(blockType); + this.then(function(){ + this.chkpt('_stairs'); + while (height > 0) { + this.traverseWidth(width, function(){ + this.setBlock(bm[0], bm[1]); + }); + + this.fwd().up(); + height -= 1; + } + this.move('_stairs'); + }); +} +module.exports = function(Drone){ + Drone.extend(stairs); +}; diff --git a/server/scriptcraft/modules/drone/test.js b/server/scriptcraft/modules/drone/test.js new file mode 100755 index 0000000..5b870b8 --- /dev/null +++ b/server/scriptcraft/modules/drone/test.js @@ -0,0 +1,26 @@ +'use strict'; +/*global module*/ +function testHorizontalStrokeWidth(){ + this.arc({ + blockType: 42, + meta: 0, + radius: 8, + orientation: 'horizontal', + strokeWidth: 3, + quadrants: {topright:true,topleft:true,bottomleft:true,bottomright:true} + }); +} +function testVerticalStrokeWidth(){ + this.arc({ + blockType: 42, + meta: 0, + radius: 8, + orientation: 'vertical', + strokeWidth: 3, + quadrants: {topright:true,topleft:true,bottomleft:true,bottomright:true} + }); +} +module.exports = function(Drone){ + Drone.prototype.testHorizontalStrokeWidth = testHorizontalStrokeWidth; + Drone.prototype.testVerticalStrokeWidth = testVerticalStrokeWidth; +}; diff --git a/server/scriptcraft/modules/drone/trees.js b/server/scriptcraft/modules/drone/trees.js new file mode 100755 index 0000000..797c418 --- /dev/null +++ b/server/scriptcraft/modules/drone/trees.js @@ -0,0 +1,99 @@ +'use strict'; +/*global require, __plugin, Packages, org, echo, module */ +var blocks = require('blocks'); +/************************************************************************ +### Drone Trees methods + + * oak() + * spruce() + * birch() + * jungle() + +#### Example + +To create 4 trees in a row, point the cross-hairs at the ground then type `/js ` and ... + + up( ).oak( ).right(8 ).spruce( ).right(8 ).birch( ).right(8 ).jungle( ); + +Trees won't always generate unless the conditions are right. You +should use the tree methods when the drone is directly above the +ground. Trees will usually grow if the drone's current location is +occupied by Air and is directly above an area of grass (That is why +the `up()` method is called first). + +![tree example](img/treeex1.png) + +None of the tree methods require parameters. Tree methods will only be +successful if the tree is placed on grass in a setting where trees can +grow. + +***/ +function bukkitTreeFactory( k, v ) { + return function( ) { + var block = this.getBlock(); + if ( block.typeId == blocks.grass ) { + this.up( ); + } + var treeLoc = this.getLocation(); + var successful = treeLoc.world.generateTree(treeLoc,v ); + if ( block.typeId == blocks.grass ) { + this.down( ); + } + }; +} +function canaryTreeFactory( k, v ){ + return function(){ + var block = this.getBlock(); + if ( block.typeId == blocks.grass ) { + this.up( ); + } + var treeLoc = this.getLocation(); + if (!treeLoc.world.generateTree){ + var msg = k + '() is not supported in this version'; + if (this.player){ + echo(this.player, msg); + } + console.log(msg); + return; + } + var cmTreeType = Packages.net.canarymod.api.world.TreeType; + var trees = { + oak: cmTreeType.BIGOAK, + birch: cmTreeType.BIRCH, + jungle: cmTreeType.JUNGLE, + spruce: cmTreeType.SPRUCE + }; + + var successful = treeLoc.world.generateTree(treeLoc, trees[k] ); + if ( block.typeId == blocks.grass ) { + this.down( ); + } + }; +} +module.exports = function (Drone){ + var trees = { + oak: null, + birch: null, + jungle: null, + spruce: null + }; + var p; + if (__plugin.canary){ + for (p in trees ) { + Drone.extend(p, canaryTreeFactory ( p, trees[p] ) ); + } + } + if (__plugin.bukkit){ + var bkTreeType = org.bukkit.TreeType; + trees = { + oak: bkTreeType.BIG_TREE , + birch: bkTreeType.BIRCH , + jungle: bkTreeType.JUNGLE, + spruce: bkTreeType.REDWOOD + }; + for (p in trees ) { + Drone.extend(p, bukkitTreeFactory ( p, trees[p] ) ); + } + } +}; + diff --git a/server/scriptcraft/modules/fireworks.js b/server/scriptcraft/modules/fireworks.js new file mode 100755 index 0000000..b8495b1 --- /dev/null +++ b/server/scriptcraft/modules/fireworks.js @@ -0,0 +1,42 @@ +/************************************************************************ +## Fireworks Module + +The fireworks module makes it easy to create fireworks using +ScriptCraft. The module has a single function `firework` which takes +a `org.bukkit.Location` as its 1 and only parameter. + +### Examples + +The module also extends the `Drone` object adding a `firework` method +so that fireworks can be created as a part of a Drone chain. For +Example.... + + /js firework() + +... creates a single firework, while .... + + /js firework().fwd(3).times(5) + +... creates 5 fireworks in a row. Fireworks have also been added as a +possible option for the `arrow` module. To have a firework launch +where an arrow strikes... + + /js arrows.firework() + +To call the fireworks.firework() function directly, you must provide a +location. For example... + + /js var fireworks = require('fireworks'); + /js fireworks.firework( self.location ); + +![firework example](img/firework.png) + +***/ + +if ( __plugin.canary ) { + exports.firework = require('./canary/fireworks'); +} else { + exports.firework = require('./bukkit/fireworks'); +} + + diff --git a/server/scriptcraft/modules/http/package.json b/server/scriptcraft/modules/http/package.json new file mode 100755 index 0000000..a143df2 --- /dev/null +++ b/server/scriptcraft/modules/http/package.json @@ -0,0 +1,4 @@ +{ + "name": "http", + "main": "./request.js" +} diff --git a/server/scriptcraft/modules/http/request.js b/server/scriptcraft/modules/http/request.js new file mode 100755 index 0000000..be39c97 --- /dev/null +++ b/server/scriptcraft/modules/http/request.js @@ -0,0 +1,137 @@ +/************************************************************************* +## Http Module + +For handling http requests. Not to be confused with the more robust +and functional 'http' module bundled with Node.js. + +### http.request() function + +The http.request() function will fetch a web address asynchronously (on a +separate thread)and pass the URL's response to a callback function +which will be executed synchronously (on the main thread). In this +way, http.request() can be used to fetch web content without blocking the +main thread of execution. + +#### Parameters + + * request: The request details either a plain URL e.g. "http://scriptcraft.js/sample.json" or an object with the following properties... + + - url: The URL of the request. + - method: Should be one of the standard HTTP methods, GET, POST, PUT, DELETE (defaults to GET). + - params: A Javascript object with name-value pairs. This is for supplying parameters to the server. + + * callback: The function to be called when the Web request has completed. This function takes the following parameters... + - responseCode: The numeric response code from the server. If the server did not respond with 200 OK then the response parameter will be undefined. + - response: A string (if the response is of type text) or object containing the HTTP response body. + +#### Example + +The following example illustrates how to use http.request to make a request to a JSON web service and evaluate its response... + +```javascript +var jsResponse; +var http = require('request'); +http.request('http://scriptcraftjs.org/sample.json',function(responseCode, responseBody){ + jsResponse = JSON.parse( responseBody ); +}); +``` +The following example illustrates a more complex use-case POSTing parameters to a CGI process on a server... + +```javascript +var http = require('http'); +http.request( { + url: 'http://pixenate.com/pixenate/pxn8.pl', + method: 'POST', + params: {script: '[]'} + }, + function( responseCode, responseBody ) { + var jsObj = JSON.parse( responseBody ); + }); +``` + +***/ + +/*global exports, encodeURI, server, __plugin, setTimeout*/ +function paramsToString( params ) { + var result = '', + paramNames = [], + i; + for ( i in params ) { + paramNames.push( i ); + } + for ( i = 0; i < paramNames.length; i++ ) { + result += paramNames[i] + '=' + encodeURI( params[ paramNames[i] ] ); + if ( i < paramNames.length-1 ) + result += '&'; + } + return result; +} +function invokeNow( fn ){ + if (__plugin.bukkit){ + server.scheduler.runTask( __plugin, fn); + return; + } + if (__plugin.canary){ + fn(); + return; + } +} +function invokeLater( fn ){ + if (__plugin.bukkit){ + server.scheduler.runTaskAsynchronously( __plugin, fn); + return; + } + if (__plugin.canary){ + setTimeout(fn,20); + return; + } +} +exports.request = function( request, callback ) { + invokeLater( function() { + var url, paramsAsString, conn, requestMethod; + if (typeof request === 'string'){ + url = request; + requestMethod = 'GET'; + }else{ + url = request.url; + paramsAsString = paramsToString( request.params ); + if ( request.method ) { + requestMethod = request.method; + } else { + requestMethod = 'GET'; + } + if ( requestMethod == 'GET' && request.params ) { + // append each parameter to the URL + url = request.url + '?' + paramsAsString; + } + } + conn = new java.net.URL( url ).openConnection(); + conn.requestMethod = requestMethod; + conn.doOutput = true; + conn.instanceFollowRedirects = false; + + if ( conn.requestMethod == 'POST' ) { + conn.doInput = true; + // put each parameter in the outputstream + conn.setRequestProperty('Content-Type', 'application/x-www-form-urlencoded'); + conn.setRequestProperty('charset', 'utf-8'); + conn.setRequestProperty('Content-Length', '' + paramsAsString.length); + conn.useCaches =false ; + var wr = new java.io.DataOutputStream(conn.getOutputStream ()); + wr.writeBytes(paramsAsString); + wr.flush(); + wr.close(); + } + var rc = conn.responseCode; + var response; + var stream; + if ( rc == 200 ) { + stream = conn.getInputStream(); + response = new java.util.Scanner( stream ).useDelimiter("\\A").next(); + } + invokeNow( function( ) { + callback( rc, response ); + }); + }); + +}; diff --git a/server/scriptcraft/modules/input.js b/server/scriptcraft/modules/input.js new file mode 100755 index 0000000..20d7581 --- /dev/null +++ b/server/scriptcraft/modules/input.js @@ -0,0 +1,63 @@ +/************************************************************************* +## Asynchronous Input Module + +The `input` module provides a simple way to prompt players for input at the +in-game prompt. In Javascript browser environments the `prompt()` function provides +a way to block execution and ask the user for input. Execution is blocked until the user +provides input using the modal dialog and clicks OK. Unfortunately Minecraft provides no +equivalent modal dialog which can be used to gather player text input. The only way to gather text +input from the player in Minecraft is to do so asynchronously. That is - a prompt message can be +sent to the player but the player is not obliged to provide input immediately, nor does the program +execution block until the player does so. + +So ScriptCraft has no `prompt()` implementation because `prompt()` is a synchronous function and +Minecraft's API provides no equivalent functions or classes which can be used to implement this synchronously. +The Minecraft API does however have a 'Conversation' API which allows for prompting of the player and asynchronously gathering text input from the player. + +This new `input()` function is best illustrated by example. The following code is for a number-guessing game: + +```javascript +var input = require('input'); +exports.numberguess = function(player){ + var randomNumber = Math.ceil(Math.random() * 10); + input( player, 'Think of a number between 1 and 10 (q to quit)', function( guess, guesser, repeat ) { + if ( guess == 'q'){ + return; + } + if ( +guess !== randomNumber ) { + if (+guess < randomNumber ) { + echo( guesser, 'Too low - guess again'); + } + if (+guess > randomNumber ) { + echo( guesser, 'Too high - guess again'); + } + repeat(); + } else { + echo( guesser, 'You guessed correctly'); + } + }); +}; +``` + +The `input()` function takes 3 parameters, the player, a prompt message and a callback which will be invoked when the player has entered some text at the in-game command prompt. +The callback is bound to an object which has the following properties: + + * sender : The player who input the text + * value : The value of the text which has been input. + * message: The message prompt. + * repeat: A function which when invoked will repeat the original prompt. (this is for flow control) + +The callback function as well as being bound to an object with the above properties (so you can use this.value inside your callback to get the value which has just been input), can also take the following parameters (in exact order): + + * value + * sender + * repeat + +The `value` parameter will be the same as `this.value`, the `repeat` parameter will be the same as `this.repeat` and so on. + +***/ +if (__plugin.canary) { + module.exports = require('./canary/input'); +} else { + module.exports = require('./bukkit/input'); +} diff --git a/server/scriptcraft/modules/inventory/index.js b/server/scriptcraft/modules/inventory/index.js new file mode 100755 index 0000000..72583dc --- /dev/null +++ b/server/scriptcraft/modules/inventory/index.js @@ -0,0 +1,43 @@ +/************************************************************************ +## Inventory Module +This module provides functions to add items to, remove items from and check the +contents of a player or NPC's inventory. + +### Usage +The inventory module is best used in conjunction with the items module. See below for examples of usage. + +```javascript +var inventory = require('inventory'); +var items = require('items'); +var utils = require('utils'); + +// gives every player a cookie and a baked potatoe +utils.players(function(player){ + inventory(player) + .add( items.cookie(1) ) + .add( items.bakedPotato(1) ) +}); + +// give a player 6 cookies then take away 4 of them + +inventory(player) + .add( items.cookie(6) ) + .remove ( items.cookie(4) ) + +// check if a player has any cookies + +var hasCookies = inventory(player).contains( items.cookie(1) ); + +``` +The inventory module exposes a single function which when passed a player or NPC will return an object with 3 methods: + +* add : Adds items to the inventory (Expects parameters of type `net.canarymod.api.inventory.Item` - I strongly recommend using the `items` module for constructing items) +* remove : removes items from the inventory (Expects parameters of type `net.canarymod.api.inventory.Item` - I strongly recommend using the `items` module for constructing items) +* contains : checks to see if there is the specified type and amount of item in the inventory (Expects parameters of type `net.canarymod.api.inventory.Item` - I strongly recommend using the `items` module for constructing items) + +***/ +if ( __plugin.canary ) { + module.exports = require('../canary/inventory'); +} else { + module.exports = require('../bukkit/inventory'); +} diff --git a/server/scriptcraft/modules/items.js b/server/scriptcraft/modules/items.js new file mode 100755 index 0000000..c5ae4cc --- /dev/null +++ b/server/scriptcraft/modules/items.js @@ -0,0 +1,5 @@ +if (__plugin.canary) { + module.exports = require('./canary/items'); +} else { + module.exports = require('./bukkit/items'); +} diff --git a/server/scriptcraft/modules/livereload.js b/server/scriptcraft/modules/livereload.js new file mode 100755 index 0000000..5be546b --- /dev/null +++ b/server/scriptcraft/modules/livereload.js @@ -0,0 +1,48 @@ +var autoload = require('plugin').autoload, + watcher = require('watcher'), + watchDir = watcher.watchDir, + unwatchDir = watcher.unwatchDir; + +var dirEventHandlers = {}; + +exports.enableLiveReloadForDir = function(dir, globalName) { + var context = {}; + reloadModules( context, dir ); + global[globalName] = context; + watchDir( dir, function( changedDir ){ + reloadModules(context, dir ); + }); +} + +exports.disableLiveReloadForDir = function(dir) { + unwatchDir( dir ); +} + +function reloadModules( context, dir ){ + /* + wph 20150118 first unregister any event handlers registered by the player + */ + var dirPath = ''+ dir.getAbsolutePath(); + var eventHandlers = dirEventHandlers[dirPath]; + if (eventHandlers){ + for (var i = 0;i < eventHandlers.length; i++){ + eventHandlers[i].unregister(); + } + eventHandlers.length = 0; + } else { + dirEventHandlers[dirPath] = []; + eventHandlers = dirEventHandlers[dirPath]; + } + /* + override events.on() so that the listener is stored here so it can be unregistered. + */ + var oldOn = events.on; + var newOn = function( eventType, fn, priority){ + var handler = oldOn(eventType, fn, priority); + eventHandlers.push(handler); + }; + events.on = newOn; + autoload( context, dir, { cache: false }); + events.on = oldOn; +} + diff --git a/server/scriptcraft/modules/minigames/scoreboard.js b/server/scriptcraft/modules/minigames/scoreboard.js new file mode 100755 index 0000000..8d7d524 --- /dev/null +++ b/server/scriptcraft/modules/minigames/scoreboard.js @@ -0,0 +1,70 @@ +'use strict'; +/*global Packages, require, server, exports*/ + +/* + wph 20150103 - temporarily commenting out - textcolors was removed. + var textcolors = require('textcolors'); +*/ +var sb; +if (__plugin.canary){ + var Canary = Packages.net.canarymod.Canary; + sb = Canary.scoreboards().getScoreboard(); +} else { + console.warn('Scoreboard not yet supported in CraftBukkit'); + return; +} +function execCommand( command ){ + server.executeVanillaCommand(server, command); +} +function getTeamByName( teamName ){ + var allTeams = sb.getTeams().toArray(); + for (var i = 0;i < allTeams.length; i++){ + if (allTeams[i].displayName == teamName){ + return allTeams[i]; + } + } + return null; +} +function createScoreboard( objectiveName, displayName ){ + execCommand('scoreboard objectives add ' + objectiveName + ' dummy ' + displayName); + execCommand('scoreboard objectives setdisplay sidebar ' + objectiveName); +} +function addTeamToScoreboard( teamName, color){ + execCommand('scoreboard teams add ' + teamName); + var team = getTeamByName( teamName ); + /* + wph 20150103 - temporarily commenting out - textcolors was removed. + team.prefix = textcolors.colorize(color, ''); + */ + //execCommand('scoreboard teams option ' + teamName + ' color ' + color); +} +function removeScoreboard( name ){ + //execCommand('scoreboard objectives remove ' + name ); + sb['removeScoreObjective(String)'](name); +} +function addPlayerToTeam( objectiveName, teamName, playerName ){ + execCommand('scoreboard teams join ' + teamName + ' ' + playerName); + execCommand('scoreboard players set ' + playerName + ' ' + objectiveName + ' -1'); + updatePlayerScore( objectiveName, playerName, 0); +} + +function updatePlayerScore( objectiveName, playerName, score ){ + /* + wph 20150801 - this fails with CanaryMod 1.8.2 so use command instead - messy for ops but non-ops won't see messages + + var sc = sb['getScore(String, ScoreObjective)']( playerName, sb.getScoreObjective( objectiveName) ); + sc.score = score; + */ + execCommand('scoreboard players set ' + playerName + ' ' + objectiveName + score); +} + +function removeTeamFromScoreboard( teamName ){ + execCommand('scoreboard teams remove ' + teamName); + //sb['removeTeam(String)'](teamName); +} +exports.create = createScoreboard; +exports.addTeam = addTeamToScoreboard; +exports.removeTeam = removeTeamFromScoreboard; +exports.addPlayerToTeam = addPlayerToTeam; +exports.updateScore = updatePlayerScore; +exports.remove = removeScoreboard; diff --git a/server/scriptcraft/modules/recipes.js b/server/scriptcraft/modules/recipes.js new file mode 100755 index 0000000..ccefbb4 --- /dev/null +++ b/server/scriptcraft/modules/recipes.js @@ -0,0 +1,34 @@ +/************************************************************************* +## The recipes module + +The Recipes module provides convenience functions for adding and removing recipes +from the game. + +### Example +To add an EnderBow to the game (assumes there's an enchanted Item variable called enderBow)... + + var recipes = require('recipes'); + var items = require('items'); + ... + var enderBowRecipe = recipes.create( { + result: enderBow, + ingredients: { + E: items.enderPearl(1), + S: items.stick(1), + W: items.string(1) + }, + shape: [ 'ESW', + 'SEW', + 'ESW' ] + } ); + // add to server + var addedRecipe = server.addRecipe( enderBowRecipe ); + // to remove... + server.removeRemove( addedRecipe ); + +***/ +if (__plugin.canary) { + module.exports = require('./canary/recipes'); +} else { + module.exports = require('./bukkit/recipes'); +} diff --git a/server/scriptcraft/modules/sc-mqtt.js b/server/scriptcraft/modules/sc-mqtt.js new file mode 100755 index 0000000..da1e135 --- /dev/null +++ b/server/scriptcraft/modules/sc-mqtt.js @@ -0,0 +1,158 @@ +'use strict'; +/************************************************************************* +## sc-mqtt module + +This module provides a simple way to communicate with devices (such as Arduino) +using the popular lightweight [MQTT protocol][mqtt]. + +### Usage + +This module can only be used if the separate `sc-mqtt.jar` file is +present in the CraftBukkit classpath. To use this module, you should +... + + 1. Download sc-mqtt.jar from + 2. Save the file to the same directory where craftbukkit.jar resides. + 3. Create a new batch file (windows-only) called + craftbukkit-sc-mqtt.bat and edit it to include the following + command... + + ```sh + java -classpath sc-mqtt.jar;craftbukkit.jar org.bukkit.craftbukkit.Main + ``` + + If you're using Mac OS, create a new craftbukkit-sc-mqtt.command + file and edit it (using TextWrangler or another text editor) ... + + ```sh + java -classpath sc-mqtt.jar:craftbukkit.jar org.bukkit.craftbukkit.Main + ``` + + 4. Execute the craftbukkit-sc-mqtt batch file / command file to start + Craftbukkit. You can now begin using this module to send and receive + messages to/from a Net-enabled Arduino or any other device which uses + the [MQTT protocol][mqtt] + + ```javascript + var mqtt = require('sc-mqtt'); + // create a new client + var client = mqtt.client( 'tcp://localhost:1883', 'uniqueClientId' ); + // connect to the broker + client.connect( { keepAliveInterval: 15 } ); + // publish a message to the broker + client.publish( 'minecraft', 'loaded' ); + // subscribe to messages on 'arduino' topic + client.subscribe( 'arduino' ); + // do something when an incoming message arrives... + client.onMessageArrived( function( topic, message ) { + console.log( 'Message arrived: topic=' + topic + ', message=' + message ); + }); + + ``` + +The `sc-mqtt` module provides a very simple minimal wrapper around the +[Eclipse Paho MQTT Version 3 Client][pahodocs] java-based MQTT +library. + +[pahodocs]: http://pic.dhe.ibm.com/infocenter/wmqv7/v7r5/index.jsp?topic=/com.ibm.mq.javadoc.doc/WMQMQxrClasses/org/eclipse/paho/client/mqttv3/package-summary.html +[mqtt]: http://mqtt.org/ + +***/ +var MISSING_MQTT = '\nMissing class org.walterhiggins.scriptcraft.ScriptCraftMqttCallback.\n' + + 'Make sure sc-mqtt.jar is in the classpath.\n' + + 'See http://github.com/walterhiggins/scriptcraft-extras-mqtt for details.\n'; + +function Client( brokerUrl, clientId ) { + + var Callback = org.walterhiggins.scriptcraft.ScriptCraftMqttCallback; + var MqttClient = org.eclipse.paho.client.mqttv3.MqttClient; + + var callback = new Callback( + function( err ) { + console.log( 'connectionLost: ' + err ); + }, + function( topic, message ) { + console.log( 'messageArrived ' + topic + '> ' + message ); + }, + function( token ) { + console.log( 'deliveryComplete:' + token ); + } + ); + + if ( !brokerUrl ) { + brokerUrl = 'tcp://localhost:1883'; + } + if ( !clientId ) { + clientId = 'scriptcraft' + new Date().getTime(); + } + var client = new MqttClient( brokerUrl, clientId, null ); + client.setCallback( callback ); + return { + connect: function( options ) { + if ( typeof options === 'undefined' ) { + client.connect(); + }else{ + client.connect(options); + } + return client; + }, + + disconnect: function( quiesceTimeout ) { + if ( typeof quiesceTimeout == 'undefined' ) { + client.disconnect(); + } else { + client.disconnect( quiesceTimeout ); + } + return client; + }, + + publish: function( topic, message, qos, retained ) { + if ( typeof message == 'string' ) { + message = new java.lang.String( message ).bytes; + } + if (typeof qos == 'undefined'){ + qos = 1; + } + if (typeof retained == 'undefined'){ + retained = false; + } + client.publish( topic, message,qos, retained ); + return client; + }, + + subscribe: function( topic ) { + client.subscribe( topic ); + return client; + }, + + unsubscribe: function( topic ) { + client.unsubscribe( topic ); + return client; + }, + + onMessageArrived: function( fn ) { + callback.setMesgArrived( fn ); + return client; + }, + + onDeliveryComplete: function( fn ) { + callback.setDeliveryComplete( fn ); + return client; + }, + + onConnectionLost: function( fn ) { + callback.setConnLost( fn ); + return client; + } + }; +} +/* + Return a new MQTT Client +*/ +exports.client = function( brokerUrl, clientId, options ) { + if ( typeof org.walterhiggins.scriptcraft.ScriptCraftMqttCallback != 'function' ) { + throw MISSING_MQTT; + } + return new Client( brokerUrl, clientId, options ); +}; + diff --git a/server/scriptcraft/modules/signs/menu.js b/server/scriptcraft/modules/signs/menu.js new file mode 100755 index 0000000..02a43c5 --- /dev/null +++ b/server/scriptcraft/modules/signs/menu.js @@ -0,0 +1,215 @@ +'use strict'; +/*global events, require, org, module, persist, __plugin*/ +var utils = require('utils'), + stringExt = require('utils/string-exts'), + store = persist('signs',{}); + +/* + Define the signs module - signs are persistent + (that is - a menu sign will still be a menu after the + server has shut down and started up) plugins now have persistent state - Yay! +*/ +var signs = { }; +var hasSign = null; +module.exports = function(hs){ + hasSign = hs; + return signs; +}; + +var setLine = null; +if (__plugin.canary){ + setLine = function(sign, i, text){ + sign.setTextOnLine( text, i); + }; +} +if (__plugin.bukkit){ + setLine = function(sign, i, text){ + sign.setLine( i, text); + }; +} + +/* + redraw a menu sign +*/ +var _redrawMenuSign = function( p_sign, p_selectedIndex, p_displayOptions ) { + var optLen = p_displayOptions.length, + i, + text; + // the offset is where the menu window begins + var offset = Math.max( 0, Math.min( optLen-3, Math.floor( p_selectedIndex/3 ) * 3) ); + for ( i = 0;i < 3; i++ ) { + text = ""; + if ( offset+i < optLen ) { + text = p_displayOptions[offset+i]; + } + if ( offset+i == p_selectedIndex ) { + text = ('' + text).replace(/^ /,">"); + } + setLine(p_sign, i+1, text); + } + if (__plugin.canary){ + p_sign.update(); + } + if (__plugin.bukkit){ + p_sign.update( true ); + } +}; + +var _updaters = {}; +/* + construct an interactive menu to be subsequently attached to + one or more Signs. +*/ +signs.menu = signMenu; + +function signMenu( label, options, callback, selectedIndex ) { + + if ( typeof selectedIndex == "undefined" ) { + selectedIndex = 0; + } + // + // variables common to all instances of this menu can go here + // + var labelPadding = "---------------"; + var optionPadding = " "; + var i; + var paddedLabel = ( labelPadding + label + labelPadding) + .substr( ( ( label.length+30 ) / 2 ) - 7, 15 ); + var optLen = options.length; + var displayOptions = []; + for ( i = 0; i < options.length; i++ ) { + displayOptions[i] = (" " + options[i] + optionPadding).substring(0,15); + } + /* + this function is returned by signs.menu and when it is invoked it will + attach menu behaviour to an existing sign in the world. + signs.menu is for use by Plugin Authors. + The function returned by signs.menu is for use by admins/ops. + */ + var convertToMenuSign = function(/* Sign */ sign, save) { + if (typeof save == "undefined") { + save = true; + } + // + // per-sign variables go here + // + var cSelectedIndex = selectedIndex; + setLine(sign, 0, paddedLabel.bold()); + var _updateSign = function( p_player, p_sign ) { + cSelectedIndex = ( cSelectedIndex + 1 ) % optLen; + _redrawMenuSign( p_sign, cSelectedIndex, displayOptions ); + var signSelectionEvent = { + player: p_player, + sign: p_sign, + text: options[ cSelectedIndex ], + number: cSelectedIndex + }; + callback( signSelectionEvent ); + }; + + /* + get a unique ID for this particular sign instance + */ + var signLoc = sign.block.location; + var menuSignSaveData = utils.locationToJSON( signLoc ); + var menuSignUID = JSON.stringify( menuSignSaveData ); + /* + keep a reference to the update function for use by the event handler + */ + _updaters[ menuSignUID ] = _updateSign; + + // initialize the sign + _redrawMenuSign( sign, cSelectedIndex, displayOptions ); + + /* + whenever a sign is placed somewhere in the world + (which is what this function does) + save its location for loading and initialization + when the server starts up again. + */ + if ( save ) { + if ( typeof store.menus == "undefined") { + store.menus = {}; + } + var signLocations = store.menus[label]; + if ( typeof signLocations == "undefined" ) { + signLocations = store.menus[label] = []; + } + signLocations.push( menuSignSaveData ); + } + return sign; + }; // end of convertToMenuSign function + + /* + a new sign definition - need to store (in-memory only) + its behaviour and bring back to life other signs of the + same type in the world. Look for other static signs in the + world with this same label and make dynamic again. + */ + + if ( store.menus && store.menus[label] ) { + var signsOfSameLabel = store.menus[ label ]; + var defragged = []; + var len = signsOfSameLabel.length; + for ( i = 0; i < len; i++ ) { + var loc = utils.locationFromJSON(signsOfSameLabel[i]); + var block = utils.blockAt(loc); + var sign = hasSign(block); + if ( sign) { + convertToMenuSign( sign, false ); + defragged.push( loc ); + } + } + /* + remove data for signs which no longer exist. + */ + if ( defragged.length != len ) { + store.menus[label] = defragged; + } + } + return convertToMenuSign; +}; + +/* +if (__plugin.canary){ + console.warn('signs/menu is not yet supported in CanaryMod'); + return; +} +*/ +if (__plugin.canary){ + events.blockRightClick( function( event ){ + var sign = hasSign(event.blockClicked); + if (! sign){ + // it's not a sign + return; + } + var evtLocStr = utils.locationToString(event.blockClicked.location); + var signUpdater = _updaters[evtLocStr]; + if ( signUpdater ) { + signUpdater( event.player, sign); + } + + }); +} +if (__plugin.bukkit){ + // + // update it every time player interacts with it. + // + events.playerInteract( function( event ) { + /* + look up our list of menu signs. If there's a matching location and there's + a sign, then update it. + */ + var sign = hasSign(event.clickedBlock); + if ( ! sign ) { + return; + } + var evtLocStr = utils.locationToString(event.clickedBlock.location); + var signUpdater = _updaters[evtLocStr]; + if ( signUpdater ) { + signUpdater( event.player, sign ); + } + }); +} + + diff --git a/server/scriptcraft/modules/signs/package.json b/server/scriptcraft/modules/signs/package.json new file mode 100755 index 0000000..520d7aa --- /dev/null +++ b/server/scriptcraft/modules/signs/package.json @@ -0,0 +1,4 @@ +{ + name: 'signs', + main: './signs.js' +} diff --git a/server/scriptcraft/modules/signs/signs.js b/server/scriptcraft/modules/signs/signs.js new file mode 100755 index 0000000..5d6d2ab --- /dev/null +++ b/server/scriptcraft/modules/signs/signs.js @@ -0,0 +1,126 @@ +'use strict'; +/*global __plugin, require, module, exports*/ +/************************************************************************ +## Signs Module + +The Signs Module can be used by plugin authors to create interactive +signs - that is - signs which display a list of choices which can be +changed by interacting (right-clicking) with the sign. + +### signs.menu() function + +This function is used to construct a new interactive menu on top of an +existing sign in the game world. + +#### Parameters + + * Label : A string which will be displayed in the topmost line of the + sign. This label is not interactive. + * options : An array of strings which can be selected on the sign by + right-clicking/interacting. + * callback : A function which will be called whenever a player + interacts (changes selection) on a sign. This callback in turn + takes as its parameter, an object with the following properties... + + * player : The player who interacted with the sign. + * sign : The [org.bukkit.block.Sign][buksign] which the player interacted with. + * text : The text for the currently selected option on the sign. + * number : The index of the currently selected option on the sign. + + * selectedIndex : optional: A number (starting at 0) indicating which + of the options should be selected by default. 0 is the default. + +#### Returns +This function does not itself do much. It does however return a +function which when invoked with a given +[org.bukkit.block.Sign][buksign] object, will convert that sign into +an interactive sign. + +#### Example: Create a sign which changes the time of day. + +##### plugins/signs/time-of-day.js + +```javascript +var utils = require('utils'), + signs = require('signs'); + +var onTimeChoice = function(event){ + var selectedIndex = event.number; + // convert to Minecraft time 0 = Dawn, 6000 = midday, 12000 = dusk, 18000 = midnight + var time = selectedIndex * 6000; + event.player.location.world.setTime(time); +}; + +// signs.menu returns a function which can be called for one or more signs in the game. +var convertToTimeMenu = signs.menu('Time of Day', + ['Dawn', 'Midday', 'Dusk', 'Midnight'], + onTimeChoice); + +exports.time_sign = function( player ){ + var sign = signs.getTargetedBy(player); + if ( !sign ) { + throw new Error('You must look at a sign'); + } + convertToTimeMenu(sign); +}; +``` + +To use the above function at the in-game prompt, look at an existing +sign and type... + + /js time_sign(self); + +... and the sign you're looking at will become an interactive sign +which changes the time each time you interact (right-click) with it. + +### signs.getTargetedBy() function + +This function takes a [org.bukkit.entity.LivingEntity][bukle] as a +parameter and returns a [org.bukkit.block.Sign][buksign] object which +the entity has targeted. It is a utility function for use by plugin authors. + +#### Example + +```javascript +var signs = require('signs'), + utils = require('utils'); +var player = utils.player('tom1234'); +var sign = signs.getTargetedBy( player ); +if ( !sign ) { + echo( player, 'Not looking at a sign'); +} +``` + +[buksign]: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/block/Sign.html +[bukle]: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/LivingEntity.html + +***/ +function hasSign( block ){ + if (__plugin.canary){ + if (block && block.tileEntity && block.tileEntity.setTextOnLine){ + return block.tileEntity; + } + } + if (__plugin.bukkit){ + if (block && block.state && block.state.setLine){ + return block.state; + } + } + return false; +} +var utils = require('utils'); +var menu = require('./menu')(hasSign); +// include all menu exports +for ( var i in menu ) { + exports[i] = menu[i]; +} + +function getTargetedBy( livingEntity ) { + var location = utils.getMousePos( livingEntity ); + if ( !location ) { + return null; + } + return hasSign(utils.blockAt(location)); +} +exports.getTargetedBy = getTargetedBy; +exports.hasSign = hasSign; diff --git a/server/scriptcraft/modules/slash.js b/server/scriptcraft/modules/slash.js new file mode 100755 index 0000000..62dd942 --- /dev/null +++ b/server/scriptcraft/modules/slash.js @@ -0,0 +1,57 @@ +'use strict'; +/*global module, require, server, __plugin*/ +var _ = require('underscore'); +/************************************************************************ +## The slash Module + +This module provides a single function which makes it easy to execute +minecraft commands via javascript. + +### The slash() function + +This function makes it easy to execute one or more minecraft commands. + +#### Parameters + + * commands : A String or Array of strings - each string is a command to be executed. + * sender: The player or server on whose behalf the commands should be executed. + +#### Examples + +Invoke the `/defaultgamemode creative` command (as server). + +```javascript +var slash = require('slash'); +slash('defaultgamemode creative', server); +``` + +Set the time of day to Midday and toggle downfall: + +```javascript +var slash = require('slash'); +slash([ + 'time set 6000', + 'toggledownfall' +], server); +``` + +***/ +function slash( commands, sender ){ + if (_.isArray(commands)){ + _.each(commands, function(command){ + slash(command, sender); + }); + return; + } + if (__plugin.canary){ + if (sender === server){ + server.consoleCommand( commands ); + } else { + server.consoleCommand( commands, sender ); + } + } + if (__plugin.bukkit){ + server.dispatchCommand(sender, commands); + } +} +module.exports = slash; diff --git a/server/scriptcraft/modules/sounds.js b/server/scriptcraft/modules/sounds.js new file mode 100755 index 0000000..4065cc3 --- /dev/null +++ b/server/scriptcraft/modules/sounds.js @@ -0,0 +1,32 @@ +/************************************************************************* +## Sounds Module + +This module is a simple wrapper around the Bukkit Sound class and provides +a simpler way to play sounds. All of the org.bukkit.Sound Enum values are attached. + +### Usage (Bukkit) : + + var sounds = require('sounds'); + sounds.play( bukkit.sound.VILLAGER_NO , self, 1, 0); // plays VILLAGER_NO sound at full volume and medium pitch + sounds.play( bukkit.sound.VILLAGER_NO , self ); // same as previous statement + +The play() function takes either a Location object or any object which has a location. +The volume parameter is in the range 0 to 1 and the pitch parameter is in the range 0 to 4. + +In addition, a play function is provided for each possible sound using the following rules: + +1. The sound is converted from ALL_CAPS_UNDERSCORE to camelCase so for example there is a sounds.villagerNo() function which will play the VILLAGER_NO sound. +2. Each such function can take 3 parameters: location (which can be either an actual Location object or an object which has a location), volume and pitch +3. Or... each such function can be called without parameters meaning the sound will be played for all online players to hear. + + sounds.villagerNo(self, 1, 0); // plays VILLAGER_NO sound at full volume and medium pitch at invoker's location + + sounds.villagerNo(); // plays VILLAGER_NO sound for all players online. + +These methods are provided for convenience to help beginners explore sounds using TAB completion. +***/ +if (__plugin.canary) { + module.exports = require('./canary/sounds'); +} else { + module.exports = require('./bukkit/sounds'); +} diff --git a/server/scriptcraft/modules/teleport.js b/server/scriptcraft/modules/teleport.js new file mode 100755 index 0000000..f98524d --- /dev/null +++ b/server/scriptcraft/modules/teleport.js @@ -0,0 +1,59 @@ +'use strict'; +/*global __plugin, org, module, require*/ +var utils = require('utils'); +/************************************************************************ +## Teleport Module + +This module provides a function to teleport entities (Players or NPCs). + +### Parameters + + * entity - The player or NPC to be teleported. If of type String, then a player with that name will be teleported. + * destination - The location to which they should be teleported. If not of type Location but is a Player, Block or any + object which has a `location` property then that works too. If of type String, then it's assumed that the destination is the player with that name. + +### Example + +The following code will teleport each player back to their spawn position. + +```javascript +var teleport = require('teleport'), + utils = require('utils'), + players = utils.players(), + i = 0; +for ( ; i < players.length; i++ ) { + teleport( players[i], players[i].spawnPosition ); +} +``` + +The following code will teleport 'tom' to 'jane's location. + +```javascript +var teleport = require('teleport'); +teleport('tom' , 'jane'); +``` +***/ +function teleport( entity, destination){ + if (typeof entity === 'String' || entity instanceof java.lang.String){ + entity = utils.player(entity); + } + if (typeof destination === 'String' || destination instanceof java.lang.String){ + var player = utils.player(destination); + if (player){ + destination = player.location; + } + } else { + if (destination.location){ + destination = destination.location; + } + } + if (__plugin.bukkit){ + var bkTeleportCause = org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + entity.teleport( destination, bkTeleportCause.PLUGIN); + } + if (__plugin.canary){ + var cmTeleportCause = Packages.net.canarymod.hook.player.TeleportHook.TeleportCause; + entity.teleportTo(destination, cmTeleportCause.PLUGIN); + } +} +module.exports = teleport; diff --git a/server/scriptcraft/modules/underscore.js b/server/scriptcraft/modules/underscore.js new file mode 100755 index 0000000..b29332f --- /dev/null +++ b/server/scriptcraft/modules/underscore.js @@ -0,0 +1,1548 @@ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); diff --git a/server/scriptcraft/modules/utils/package.json b/server/scriptcraft/modules/utils/package.json new file mode 100755 index 0000000..d80809d --- /dev/null +++ b/server/scriptcraft/modules/utils/package.json @@ -0,0 +1,4 @@ +{ + "name": 'utils', + "main": './utils.js' +} diff --git a/server/scriptcraft/modules/utils/string-exts.js b/server/scriptcraft/modules/utils/string-exts.js new file mode 100755 index 0000000..14b767d --- /dev/null +++ b/server/scriptcraft/modules/utils/string-exts.js @@ -0,0 +1,79 @@ +'use strict'; +/************************************************************************ +String class extensions +----------------------- +The following chat-formatting methods are added to the javascript String class.. + + * aqua() + * black() + * blue() + * bold() + * brightgreen() + * darkaqua() + * darkblue() + * darkgray() + * darkgreen() + * purple() + * darkpurple() + * darkred() + * gold() + * gray() + * green() + * italic() + * lightpurple() + * indigo() + * green() + * red() + * pink() + * yellow() + * white() + * strike() + * random() + * magic() + * underline() + * reset() + +Example +------- + + /js var boldGoldText = "Hello World".bold().gold(); + /js echo(self, boldGoldText ); + +

Hello World

+ +***/ +var COLOR_CHAR = '\u00a7'; +var formattingCodes = { + aqua: 'b', + black: '0', + blue: '9', + bold: 'l', + brightgreen: 'a', + darkaqua: '3', + darkblue: '1', + darkgray: '8', + darkgreen: '2', + purple: 'd', + darkpurple: '5', + darkred: '4', + gold: '6', + gray: '7', + green: 'a', + italic: 'o', + lightpurple: 'd', + indigo: '9', + red: 'c', + pink: 'd', + yellow: 'e', + white: 'f', + strike: 'm', + random: 'k', + magic: 'k', + underline: 'n', + reset: 'r' +}; +for ( var method in formattingCodes ) { + String.prototype[method] = function( c ) { + return function(){ return c + this; }; + }( COLOR_CHAR + formattingCodes[method] ); +} diff --git a/server/scriptcraft/modules/utils/utils.js b/server/scriptcraft/modules/utils/utils.js new file mode 100755 index 0000000..82ed01f --- /dev/null +++ b/server/scriptcraft/modules/utils/utils.js @@ -0,0 +1,742 @@ +/*global require, __plugin, org, exports, server, setTimeout, Packages, setInterval, addUnloadHandler, clearInterval, events*/ +'use strict'; +var File = java.io.File; + +if (__plugin.bukkit){ + var bkBukkit = org.bukkit.Bukkit, + bkLocation = org.bukkit.Location, + bkBlockCommandSender = org.bukkit.command.BlockCommandSender; +} +if (__plugin.canary){ + var Canary = Packages.net.canarymod.Canary; +} +/************************************************************************ +## Utilities Module + +The `utils` module is a storehouse for various useful utility +functions which can be used by plugin and module authors. It contains +miscellaneous utility functions and classes to help with programming. + +### utils.player() function + +The utils.player() function will return a [Player][cmpl] object +with the given name. This function takes a single parameter +`playerName` which can be either a String or a [Player][cmpl] object - +if it's a Player object, then the same object is returned. If it's a +String, then it tries to find the player with that name. + +#### Parameters + + * playerName : A String or Player object. If no parameter is provided + then player() will try to return the `self` variable . It is + strongly recommended to provide a parameter. + +#### Example + +```javascript +var utils = require('utils'); +var name = 'walterh'; +var player = utils.player(name); +if ( player ) { + echo(player, 'Got ' + name); +} else { + console.log('No player named ' + name); +} +``` + +[bkpl]: http://jd.bukkit.org/dev/apidocs/org/bukkit/entity/Player.html +[cmpl]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/api/entity/living/humanoid/Player.html +[cmloc]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/api/world/position/Location.html +[bkloc]: http://jd.bukkit.org/dev/apidocs/org/bukkit/Location.html + +***/ +function _player( playerName ) { + if ( typeof playerName == 'undefined' ) { + if ( typeof self == 'undefined' ) { + return null; + } else { + return self; + } + } else { + if ( typeof playerName == 'string' ) + if (__plugin.canary) { + return Canary.server.getPlayer( playerName ); + } else { + return bkBukkit.getPlayer( playerName ); + } + else + return playerName; // assumes it's a player object + } +}; +/************************************************************************* +### utils.world( worldName ) function + +Returns a World object matching the given name + +***/ +function _world( worldName ){ + if (__plugin.canary){ + if (worldName instanceof Packages.net.canarymod.api.world.World){ + return worldName; + } + var worldMgr = Canary.server.worldManager; + try { + if (worldName === undefined){ + var worldNames = worldMgr.getLoadedWorldsNames(); + worldName = worldNames[0]; + } + return worldMgr.getWorld( worldName, true ); + } catch (error) { + console.error( 'utils.world() failed to load ' + worldName + ',Error:' + error ); + } + } + if (__plugin.bukkit){ + if (worldName instanceof org.bukkit.World){ + return worldName; + } + if (worldName === undefined){ + return bkBukkit.getWorlds().get(0); + } + return bkBukkit.getWorld( worldName ); + } + return null; +} +exports.world = _world; + +/************************************************************************* +### utils.blockAt( Location ) function + +Returns the Block at the given location. + +***/ +function _blockAt( location ){ + if (__plugin.canary){ + return location.world.getBlockAt(location); + } + if (__plugin.bukkit){ + return location.block; + } + return null; +} +exports.blockAt = _blockAt; +/************************************************************************* +### utils.locationToJSON() function + +utils.locationToJSON() returns a [Location][cmloc] object in JSON form... + + { world: 'world5', + x: 56.9324, + y: 103.9954, + z: 43.1323, + yaw: 0.0, + pitch: 0.0 + } + +This can be useful if you write a plugin that needs to store location data since bukkit's Location object is a Java object which cannot be serialized to JSON by default. + +#### Parameters + + * location: An object of type [Location][cmloc] + +#### Returns + +A JSON object in the above form. + +***/ +function _locationToJSON( location ) { + var yaw = __plugin.bukkit ? location.yaw : (__plugin.canary ? location.rotation : 0); + return { + world: ''+location.world.name, + x: location.x, + y: location.y, + z: location.z, + yaw: yaw, + pitch: location.pitch + }; +}; +/************************************************************************* +### utils.locationToString() function + +The utils.locationToString() function returns a +[Location][cmloc] object in string form... + + '{"world":"world5",x:56.9324,y:103.9954,z:43.1323,yaw:0.0,pitch:0.0}' + +... which can be useful if you write a plugin which uses Locations as +keys in a lookup table. + +#### Example + +```javascript +var utils = require('utils'); +... +var key = utils.locationToString(player.location); +lookupTable[key] = player.name; +``` + +***/ +exports.locationToString = function locationToString( location ) { + return JSON.stringify( _locationToJSON( location ) ); +}; +exports.locationToJSON = _locationToJSON; + +/************************************************************************* +### utils.locationFromJSON() function + +This function reconstructs an [Location][cmloc] object from +a JSON representation. This is the counterpart to the +`locationToJSON()` function. It takes a JSON object of the form +returned by locationToJSON() and reconstructs and returns a bukkit +Location object. + +***/ +exports.locationFromJSON = function locationFromJSON( json ) { + var world; + if ( json.constructor == Array ) { + // for support of legacy format + world = _world( json[0] ); + return new bkLocation( world, json[1], json[2] , json[3] ); + } else { + if (__plugin.canary){ + world = _world( json.world ); + var cmLocation = Packages.net.canarymod.api.world.position.Location; + return new cmLocation(world, json.x, json.y, json.z, json.pitch?json.pitch:0, json.yaw?json.yaw:0); + } else { + world = _world( json.world ); + return new bkLocation( world, json.x, json.y , json.z, json.yaw?json.yaw:0, json.pitch?json.pitch:0 ); + } + } +}; + +exports.player = _player; + +exports.getPlayerObject = function getPlayerObject( player ) { + console.warn( 'utils.getPlayerObject() is deprecated. Use utils.player() instead.' ); + return _player(player); +}; +/************************************************************************* +### utils.getPlayerPos() function + +This function returns the player's [Location][cmloc] (x, y, z, pitch +and yaw) for a named player. If the "player" is in fact a +[BlockCommand][bkbcs] then the attached Block's location is returned. + +#### Parameters + + * player : A [org.bukkit.command.CommandSender][bkbcs] (Player or BlockCommandSender) or player name (String). + +#### Returns + +A [Location][cmloc] object. + +[bkbcs]: http://jd.bukkit.org/dev/apidocs/org/bukkit/command/BlockCommandSender.html +[bksndr]: http://jd.bukkit.org/dev/apidocs/index.html?org/bukkit/command/CommandSender.html +***/ +function getPlayerPos( player ){ + player = _player( player ); + if ( player ) { + if (__plugin.bukkit){ + if ( player instanceof bkBlockCommandSender ) + return player.block.location; + else + return player.location; + } + if (__plugin.canary){ + if ( player instanceof Packages.net.canarymod.api.world.blocks.CommandBlock) + return player.block.location; + else + return player.location; + } + } + return null; +} +exports.getPlayerPos = getPlayerPos; +/************************************************************************ +### utils.getMousePos() function + +This function returns a [Location][cmloc] object (the +x,y,z) of the current block being targeted by the named player. This +is the location of the block the player is looking at (targeting). + +#### Parameters + + * player : The player whose targeted location you wish to get. + +#### Example + +The following code will strike lightning at the location the player is looking at... + +```javascript +var utils = require('utils'); +var playerName = 'walterh'; +var targetPos = utils.getMousePos(playerName); +if (targetPos){ + if (__plugin.canary){ + targetPos.world.makeLightningBolt(targetPos); + } + if (__plugin.bukkit){ + targetPos.world.strikeLightning(targetPos); + } +} +``` + +***/ +exports.getMousePos = function getMousePos( player ) { + + player = _player(player); + if ( !player ) { + return null; + } + var targetedBlock ; + if ( __plugin.canary ) { + var cmLineTracer = Packages.net.canarymod.LineTracer; + var lineTracer = new cmLineTracer(player); + targetedBlock = lineTracer.getTargetBlock(); + if (targetedBlock == null){ + return null; + } + } else { + // player might be CONSOLE or a CommandBlock + if ( !player.getTargetBlock ) { + return null; + } + try { + targetedBlock = player.getTargetBlock( null, 5 ); + }catch (e){ + // spigot 1.8.7 adds new overload which causes problems with JDK 7 + targetedBlock = player['getTargetBlock(java.util.Set,int)'](null, 5 ); + } + if ( targetedBlock == null || targetedBlock.isEmpty() ) { + return null; + } + } + return targetedBlock.location; +}; +/************************************************************************ +### utils.foreach() function + +The utils.foreach() function is a utility function for iterating over +an array of objects (or a java.util.Collection of objects) and +processing each object in turn. Where utils.foreach() differs from +other similar functions found in javascript libraries, is that +utils.foreach can process the array immediately or can process it +*nicely* by processing one item at a time then delaying processing of +the next item for a given number of server ticks (there are 20 ticks +per second on the minecraft main thread). This method relies on +Bukkit's [org.bukkit.scheduler][sched] package for scheduling +processing of arrays. + +[sched]: http://jd.bukkit.org/beta/apidocs/org/bukkit/scheduler/package-summary.html + +#### Parameters + + * array : The array to be processed - It can be a javascript array, a java array or java.util.Collection + * callback : The function to be called to process each item in the + array. The callback function should have the following signature + `callback(item, index, object, array)`. That is the callback will + be called with the following parameters.... + + - item : The item in the array + - index : The index at which the item can be found in the array. + - object : Additional (optional) information passed into the foreach method. + - array : The entire array. + + * context (optional) : An object which may be used by the callback. + * delayInMilliseconds (optional, numeric) : If a delay is specified then the processing will be scheduled so that + each item will be processed in turn with a delay between the completion of each + item and the start of the next. This is recommended for any CPU-intensive process. + * onDone (optional, function) : A function to be executed when all processing + is complete. This parameter is only used when the processing is delayed. (It's optional even if a + delay parameter is supplied). + +If called with a delay parameter then foreach() will return +immediately after processing just the first item in the array (all +subsequent items are processed later). If your code relies on the +completion of the array processing, then provide an `onDone` parameter +and put the code there. + +#### Example + +The following example illustrates how to use foreach for immediate processing of an array... + +```javascript +var utils = require('utils'); +var players = utils.players(); +utils.foreach (players, function( player ) { + echo( player , 'Hi ' + player); +}); +``` + +... The `utils.foreach()` function can work with Arrays or any +Java-style collection. This is important because many objects in the +CanaryMod and Bukkit APIs use Java-style collections. +***/ +function _foreach( array, callback, context, delay, onCompletion ) { + if ( array instanceof java.util.Collection ) { + array = array.toArray(); + } + var i = 0; + var len = array.length; + function next() { + callback(array[i], i, context, array); + i++; + } + function hasNext() { + return i < len; + } + if ( delay ) { + _nicely( next, hasNext, onCompletion, delay ); + } else { + for ( ;i < len; i++ ) { + callback( array[i], i, context, array ); + } + } +}; +exports.foreach = _foreach; +/************************************************************************ +### utils.nicely() function + +The utils.nicely() function is for performing background processing. utils.nicely() lets you +process with a specified delay between the completion of each `next()` +function and the start of the next `next()` function. +`utils.nicely()` is a recursive function - that is - it calls itself +(schedules itself actually) repeatedly until `hasNext` returns false. + +#### Parameters + + * next : A function which will be called if processing is to be done. + * hasNext : A function which is called to determine if the `next` + callback should be invoked. This should return a boolean value - + true if the `next` function should be called (processing is not + complete), false otherwise. + * onDone : A function which is to be called when all processing is complete (hasNext returned false). + * delayInMilliseconds : The delay between each call. + +#### Example + +See the source code to utils.foreach for an example of how utils.nicely is used. + +***/ +function _nicely( next, hasNext, onDone, delay ) { + if ( hasNext() ){ + next(); + setTimeout( function() { + _nicely( next, hasNext, onDone, delay ); + }, delay ); + }else{ + if ( onDone ) { + onDone(); + } + } +}; +exports.nicely = _nicely; + +function _at( time24hr, callback, pWorlds, repeat ) { + console.warn("utils.at() is deprecated, use require('at') instead"); + var at = require('at'); + return at( time24hr, callback, pWorlds, repeat); +} +exports.at = _at; +/************************************************************************* +### utils.time( world ) function + +Returns the timeofday (in minecraft ticks) for the given world. This function is necessary because +canarymod and bukkit differ in how the timeofday is calculated. + +See http://minecraft.gamepedia.com/Day-night_cycle#Conversions + +***/ +function getTime(world){ + world = _world(world); + + if (__plugin.bukkit){ + return world.time; + } + if (__plugin.canary){ + // there's a bug in canary where if you call world.setTime() the world.totalTime + // becomes huge. + if (world.totalTime < world.rawTime){ + return world.totalTime; + } else { + return ((world.totalTime % world.rawTime) + world.relativeTime) % 24000; + } + } + return 0; +} +exports.time = getTime; + +/************************************************************************* +### utils.time24( world ) function + +Returns the timeofday for the given world using 24 hour notation. (number of minutes) + +See http://minecraft.gamepedia.com/Day-night_cycle#Conversions + +#### Parameters + + * world : the name of the world or world object for which you want to get time + +***/ +function getTime24( world ){ + world = _world(world); // accept world name or object or undeifned + var mcTime = getTime(world); + var mins = Math.floor( ( (mcTime + 6000) % 24000) / 16.6667 ); + return mins; +} +exports.time24 = getTime24; + +/************************************************************************ +### utils.find() function + +The utils.find() function will return a list of all files starting at +a given directory and recursiving trawling all sub-directories. + +#### Parameters + + * dir : The starting path. Must be a string. + * filter : (optional) A [FilenameFilter][fnfltr] object to return only files matching a given pattern. + +[fnfltr]: http://docs.oracle.com/javase/6/docs/api/java/io/FilenameFilter.html + +#### Example + +```javascript +var utils = require('utils'); +var jsFiles = utils.find('./', function(dir,name){ + return name.match(/\.js$/); +}); +``` +***/ +exports.find = function( path, filter){ + console.warn("utils.find() is deprecated, use require('find') instead"); + return require('find')(path, filter); +}; +/************************************************************************ +### utils.serverAddress() function + +The utils.serverAddress() function returns the IP(v4) address of the server. + +```javascript +var utils = require('utils'); +var serverAddress = utils.serverAddress(); +console.log(serverAddress); +``` +***/ +exports.serverAddress = function serverAddress() { + var interfaces = java.net.NetworkInterface.getNetworkInterfaces(); + var current, + addresses, + current_addr; + while ( interfaces.hasMoreElements() ) { + current = interfaces.nextElement(); + if ( ! current.isUp() || current.isLoopback() || current.isVirtual() ) { + continue; + } + addresses = current.getInetAddresses(); + while (addresses.hasMoreElements()) { + current_addr = addresses.nextElement(); + if ( current_addr.isLoopbackAddress() ) + continue; + if ( current_addr instanceof java.net.Inet4Address) + return current_addr.getHostAddress(); + } + } + return null; +}; +/************************************************************************** +### utils.array() function + +Converts Java collection objects to type Javascript array so they can avail of +all of Javascript's Array goodness. + +#### Example + + var utils = require('utils'); + var worlds = utils.array(server.worldManager.getAllWorlds()); + +***/ +function toArray( ){ + var result = [], + javaArray = null, + i = 0; + if (arguments[0] instanceof java.util.Collection){ + // it's a java collection + javaArray = arguments[0].toArray(); + for ( ;i < javaArray.length; i++) { + result.push(javaArray[i]); + } + } else if (arguments[0].constructor === Array){ + // it's a javascript array + return arguments[0]; + } else if (arguments[0].length) { + // it's a java array + javaArray = arguments[0]; + for ( ;i < javaArray.length; i++) { + result.push(javaArray[i]); + } + } + return result; +} +exports.array = toArray; + +function worlds(){ + if (__plugin.canary){ + return toArray(server.worldManager.allWorlds); + } + if (__plugin.bukkit){ + return toArray(server.worlds); + } +} +exports.worlds = worlds; + +/************************************************************************* +### utils.players() function + +This function returns a javascript array of all online players on the +server. You can optionally provide a function which will be invoked +with each player as a parameter. For example, to give each player the +ability to shoot arrows which launch fireworks: + +```javascript +require('utils').players( arrows.firework ) +``` + +Any players with a bow will be able to launch fireworks by shooting. + +### utils.playerNames() function + +This function returns a javascript array of player names (as javascript strings) + +***/ +function getPlayersBukkit(){ + var result = []; + for (var i = 0; i < server.onlinePlayers.length; i++){ + result.push(server.onlinePlayers[i]); + } + return result; +} +function getPlayersCanary(){ + var result = []; + var players = server.playerList; + for (var i = 0; i < players.size(); i++){ + result.push(players.get(i)); + } + return result; +} +var getPlayers = null; +if (__plugin.canary) { + getPlayers = getPlayersCanary; +} else { + getPlayers = getPlayersBukkit; +} + +function getStatBukkit(){ + if (arguments.length == 1){ + var stat = arguments[1]; + return org.bukkit.Statistic[stat.toUpperCase()]; + } else { + var player = arguments[0]; + var stat = arguments[1]; + return player.getStatistic(org.bukkit.Statistic[stat.toUpperCase()]); + } + +} +function getStatCanary(){ + var cmStatistics = Packages.net.canarymod.api.statistics.Statistics; + if (arguments.length == 1){ + var stat = arguments[0]; + return cmStatistics[stat.toUpperCase()].instance; + } else { + var player = arguments[0]; + var stat = arguments[1]; + return player.getStat(cmStatistics[stat.toUpperCase()].instance); + } +} +if (__plugin.canary){ + var cmStatistics = Packages.net.canarymod.api.statistics.Statistics; + var values = cmStatistics.values(); + for (var i = 0;i < values.length; i++){ + var value = values[i]; + try { + var stat = value.instance; + getStatCanary[value.name()] = stat; + }catch (e){ + // as of 20141018 some calls to getInstance() will generate an NPE + // see https://github.com/CanaryModTeam/CanaryMod/issues/84 + } + } +} + +function getPlayerNames(){ + return getPlayers().map(function(p){ return p.name; }); +} +exports.players = function players(fn){ + var result = getPlayers(); + if (fn){ + result.forEach(fn); + } + return result; +}; +exports.playerNames = getPlayerNames; + +/************************************************************************* +### utils.stat() function + +This function returns a numeric value for a given player statistic. + +#### Parameters + + * Player - The player object (optional - if only the statistic name parameter is provided then the statistic object is returned) + * Statistic - A string whose value should be one of the following (CanaryMod) + * ANIMALSBRED + * BOATONECM + * CLIMBONECM + * CROUCHONECM + * DAMAGEDEALT + * DAMAGETAKEN + * DEATHS + * DRIVEONECM + * DROP + * FALLONECM + * FISHCAUGHT + * FLYONECM + * HORSEONECM + * JUMP + * JUNKFISHED + * LEAVEGAME + * MINECARTONECM + * MOBKILLS + * PIGONECM + * PLAYERKILLS + * PLAYONEMINUTE + * SPRINTONECM + * SWIMONECM + * TALKEDTOVILLAGER + * TIMESINCEDEATH + * TRADEDWITHVILLAGER + * TREASUREFISHED + * WALKONECM + +See [CanaryMod's Statistic][cmstat] class for an up-to-date list of possible stat values + +[cmstat]: https://ci.visualillusionsent.net/job/CanaryLib/javadoc/net/canarymod/api/statistics/Statistics.html + +#### Example 1 Getting stats for a player + + var utils = require('utils'); + var jumpCount = utils.stat( player, 'jump'); + +#### Example 2 Getting the JUMP statistic object (which can be used elsewhere) + + var utils = require('utils'); + var JUMPSTAT = utils.stat('jump'); + var jumpCount = player.getStat( JUMPSTAT ); // canary-specific code + +This function also contains values for each possible stat so you can get at stats like this... + + var utils = require('utils'); + var JUMPSTAT = utils.stat.JUMP; // Accessing the value + var jumpCount = player.getStat ( JUMPSTAT ); // canary-specific code +***/ +exports.stat = __plugin.canary ? getStatCanary: getStatBukkit; + diff --git a/server/scriptcraft/modules/watcher.js b/server/scriptcraft/modules/watcher.js new file mode 100755 index 0000000..7970d6c --- /dev/null +++ b/server/scriptcraft/modules/watcher.js @@ -0,0 +1,189 @@ +'use strict'; +/*global setTimeout, exports, require*/ +var File = java.io.File; +/************************************************************************ +## The watcher Module + +This module exposes functions for watching for changes to files or directories. + +### watcher.watchFile() function + +Watches for changes to the given file or directory and calls the function provided +when the file changes. + +#### Parameters + + * File - the file to watch (can be a file or directory) + * Callback - The callback to invoke when the file has changed. The callback takes the + changed file as a parameter. + +#### Example + +```javascript +var watcher = require('watcher'); +watcher.watchFile( 'test.txt', function( file ) { + console.log( file + ' has changed'); +}); +``` +***/ +var filesWatched = {}; +var dirsWatched = {}; + +exports.watchFile = function( file, callback ) { + if ( typeof file == 'string' ) { + file = new File(file); + } + filesWatched[file.canonicalPath] = { + callback: callback, + lastModified: file.lastModified() + }; +}; + +/************************************************************************ +### watcher.watchDir() function + +Watches for changes to the given directory and calls the function provided +when the directory changes. It works by calling watchFile/watchDir for each +file/subdirectory. + +#### Parameters + + * Dir - the file to watch (can be a file or directory) + * Callback - The callback to invoke when the directory has changed. + The callback takes the changed file as a parameter. + For each change inside the directory the callback will also + be called. + +#### Example + +```javascript +var watcher = require('watcher'); +watcher.watchDir( 'players/_ial', function( dir ) { + console.log( dir + ' has changed'); +}); +``` +***/ + +exports.watchDir = function( dir, callback ) { + if ( typeof dir == 'string' ) { + dir = new File(dir); + } + dirsWatched[dir.canonicalPath] = { + callback: callback, + lastModified: dir.lastModified() + }; + + var files = dir.listFiles(),file; + if ( !files ) { + return; + } + for ( var i = 0; i < files.length; i++ ) { + file = files[i]; + if (file.isDirectory( )) { + exports.watchDir(file,callback); + }else{ + exports.watchFile(file,callback); + } + } +}; +/************************************************************************ +### watcher.unwatchFile() function + +Removes a file from the watch list. + +#### Example +```javascript +var watcher = require('watcher'); +watcher.unwatchFile('test.txt'); +``` + +***/ +exports.unwatchFile = function( file, callback ) { + if ( typeof file == 'string' ) { + file = new File(file); + } + delete filesWatched[file.canonicalPath]; +}; + +/************************************************************************ +### watcher.unwatchDir() function + +Removes a directory from the watch list and all files inside the directory +are also "unwatched" + +#### Example +```javascript +var watcher = require('watcher'); +watcher.unwatchDir ('players/_ial'); +``` +Would cause also +```javascript +watcher.unwatchFile (file); +``` +for each file inside directory (and unwatchDir for each directory inside it) + +***/ +exports.unwatchDir = function( dir, callback ) { + if ( typeof dir == 'string' ) { + dir = new File(dir); + } + delete dirsWatched[dir.canonicalPath]; + + var files = dir.listFiles(),file; + if ( !files ) { + return; + } + for ( var i = 0; i < files.length; i++ ) { + file = files[i]; + if (file.isDirectory( )) { + exports.unwatchDir(file,callback); + }else{ + exports.unwatchFile(file,callback); + } + } +}; + +function fileWatcher(calledCallbacks) { + for (var file in filesWatched) { + var fileObject = new File(file); + var lm = fileObject.lastModified(); + if ( lm != filesWatched[file].lastModified ) { + filesWatched[file].lastModified = lm; + filesWatched[file].callback(fileObject); + if (!fileObject.exists()) { + exports.unwatchFile(file,filesWatched[file].callback); + } + } + } +}; + + +//monitors directories for time change +//when a change is detected watchFiles are invoked for each of the files in directory +//and callback is called +function dirWatcher(calledCallbacks) { + for (var dir in dirsWatched) { + var dirObject = new File(dir); + var lm = dirObject.lastModified(); + var dw = dirsWatched[dir]; + if ( lm != dirsWatched[dir].lastModified ) { + dirsWatched[dir].lastModified = lm; + dirsWatched[dir].callback(dirObject); + + exports.unwatchDir(dir, dw.callback); + //causes all files to be rewatched + if (dirObject.exists()) { + exports.watchDir(dir, dw.callback); + } + } + } +}; + +//guarantees that a callback is only called once for each change +function monitorDirAndFiles() { + fileWatcher (); + dirWatcher (); + setTimeout( monitorDirAndFiles, 3000 ); +}; + +setTimeout( monitorDirAndFiles, 3000 ); diff --git a/server/scriptcraft/plugins/alias/alias.js b/server/scriptcraft/plugins/alias/alias.js new file mode 100755 index 0000000..9b0998c --- /dev/null +++ b/server/scriptcraft/plugins/alias/alias.js @@ -0,0 +1,253 @@ +'use strict'; +/************************************************************************* +## alias Plugin + +The alias module lets players and server admins create their own +per-player or global custom in-game command aliases. + +### Examples + +To set a command alias which is only visible to the current player +(per-player alias)... + + /jsp alias set cw = time set {1} ; weather {2} + +... Creates a new custom command only usable by the player who set +it called `cw` (short for set Clock and Weather) which when invoked... + + /cw 4000 sun + +... will perform the following commands... + + /time set 4000 + /weather sun + +Aliases can use paramters as above. On the right hand side of the `=`, the +`{1}` refers to the first parameter provided with the `cw` alias, `{2}` +refers to the second parameter and so on. So `cw 4000 sun` is converted to +`time set 4000` and `weather sun`. + +To set a global command alias usable by all (only operators can create +such an alias)... + + /jsp alias global stormy = time 18000; weather storm + +To remove an alias ... + + /jsp alias remove cw + +... removes the 'cw' alias from the appropriate alias map. + +To get a list of aliases currently defined... + + /jsp alias list + +To get help on the `jsp alias` command: + + /jsp alias help + +Aliases can be used at the in-game prompt by players or in the server +console. Aliases will not be able to avail of command autocompletion +(pressing the TAB key will have no effect). + +***/ + +var _usage = '\ +/jsp alias set {alias} = {comand-1} ;{command-2}\n \ +/jsp alias global {alias} = {command-1} ; {command-2}\n \ +/jsp alias list\n \ +/jsp alias remove {alias}\n \ +Create a new alias : \n \ +/jsp alias set cw = time set {1} ; weather {2}\n \ +Execute the alias : \n \ +/cw 4000 sun \n \ +...is the same as \'/time set 4000\' and \'/weather sun\''; +/* + persist aliases +*/ +var _store = { + players: {}, + global: {} +}; +/* + turns 'cw = time set {1} ; weather {2}' into {cmd: 'cw', aliases: ['time set {1}', 'weather {2}']} + _processParams is a private function which takes an array of parameters + used for the 'set' and 'global' options. +*/ +var _processParams = function( params ) { + var paramStr = params.join(' '), + eqPos = paramStr.indexOf('='), + aliasCmd = paramStr.substring( 0, eqPos).trim(), + aliasValue = paramStr.substring( eqPos + 1 ).trim(); + return { + cmd: aliasCmd, + aliases: aliasValue.split( /\s*;\s*/ ) + }; +}; + +var _set = function( params, player ) { + var playerAliases = _store.players[player.name]; + if (!playerAliases ) { + playerAliases = {}; + } + var o = _processParams( params ); + playerAliases[o.cmd] = o.aliases; + _store.players[player.name] = playerAliases; + echo( player, 'Alias ' + o.cmd + ' created.' ); +}; + +var _remove = function( params, player ) { + if ( _store.players[player.name] && _store.players[player.name][ params[0] ] ) { + delete _store.players[player.name][params[0]]; + echo( player, 'Alias ' + params[0] + ' removed.' ); + } + else{ + echo( player, 'Alias ' + params[0] + ' does not exist.' ); + } + if ( isOp(player) ) { + if ( _store.global[params[0]] ) { + delete _store.global[params[0]]; + } + } +}; + +var _global = function( params, player ) { + if ( !isOp(player) ) { + echo( player, 'Only operators can set global aliases. ' + + 'You need to be an operator to perform this command.' ); + return; + } + var o = _processParams( params ); + _store.global[o.cmd] = o.aliases; + echo( player, 'Global alias ' + o.cmd + ' created.' ); +}; + +var _list = function( params, player ) { + var alias = 0; + try { + if ( _store.players[player.name] ) { + echo( player, 'Your aliases:'); + for ( alias in _store.players[player.name] ) { + echo( player, alias + ' = ' + + JSON.stringify( _store.players[player.name][alias] ) ); + } + } else { + echo( player, 'You have no player-specific aliases.' ); + } + echo( player, 'Global aliases:' ); + for ( alias in _store.global ) { + echo( player, alias + ' = ' + JSON.stringify( _store.global[alias] ) ); + } + } catch( e ) { + console.error( 'Error in list function: ' + e.message ); + throw e; + } +}; +var _help = function( params, player ) { + echo( player, 'Usage:\n' + _usage ); +}; + +var alias = plugin( 'alias', { + store: _store, + set: _set, + global: _global, + remove: _remove, + list: _list, + help: _help +}, true ); + +var aliasCmd = command( 'alias', function( params, invoker ) { + var operation = params[0], + fn; + if ( !operation ) { + echo( invoker, 'Usage:\n' + _usage ); + return; + } + /* + wph 20140122 this is kind of dumb but Nashorn has some serious problems + accessing object properties by array index notation + in JRE8 alias[operation] returns null - definitely a bug in Nashorn. + */ + for ( var key in alias ) { + if ( key == operation ) { + fn = alias[key]; + fn( params.slice(1), invoker ); + return; + } + } + echo( invoker, 'Usage:\n' + _usage ); +}); + +var _intercept = function( msg, invoker, exec ) { + if ( msg.trim().length == 0 ) + return false; + var msgParts = msg.split(' '), + command = msg.match( /^\/*([^\s]+)/ )[1], + template = [], + isAlias = false, + cmds = [], + commandObj, + filledinCommand, + i; + + if ( _store.global[command] ) { + template = _store.global[command]; + isAlias = true; + } + /* + allows player-specific aliases to override global aliases + */ + if ( _store.players[invoker] && _store.players[invoker][command] ) { + template = _store.players[invoker][command]; + isAlias = true; + } + for ( i = 0; i < template.length; i++) { + filledinCommand = template[i].replace( /{([0-9]+)}/g, function( match, index ) { + index = parseInt( index, 10 ); + if ( msgParts[index] ) { + return msgParts[index]; + } else { + return match; + } + }); + cmds.push( filledinCommand ); + } + + for (i = 0; i< cmds.length; i++ ) { + exec( cmds[i] ); + } + return isAlias; + +}; +/* + Intercept all command processing and replace with aliased commands if the + command about to be issued matches an alias. +*/ +if (__plugin.canary){ + console.warn('alias plugin is not yet supported in CanaryMod'); + return; +} +events.playerCommandPreprocess( function( evt ) { + var invoker = evt.player; + var exec = function( cmd ) { + invoker.performCommand(cmd); + }; + var isAlias = _intercept( (''+evt.message).trim(), ''+invoker.name, exec); + if ( isAlias ) { + evt.cancelled = true; + } +}); +/* define a 'void' command because ServerCommandEvent can't be canceled */ +command('void',function( ) { +} ); + +events.serverCommand( function( evt ) { + var invoker = evt.sender; + var exec = function( cmd ) { + invoker.server.dispatchCommand( invoker, cmd); + }; + var isAlias = _intercept( (''+evt.command).trim(), ''+ invoker.name, exec ); + if ( isAlias ) { + evt.command = 'jsp void'; + } +}); diff --git a/server/scriptcraft/plugins/arrows.js b/server/scriptcraft/plugins/arrows.js new file mode 100755 index 0000000..212b153 --- /dev/null +++ b/server/scriptcraft/plugins/arrows.js @@ -0,0 +1,171 @@ +'use strict'; +/*global require, __plugin, exports, events, setTimeout */ +/************************************************************************* +## Arrows Plugin + +The arrows mod adds fancy arrows to the game. Arrows which ... + + * Launch fireworks. + * Explode on impact. + * Force Lightning to strike where they land. + * Teleport the player to the landing spot. + * Spawn Trees at the landing spot. + +### Usage: + + * `/js arrows.firework(self)` - A firework launches where the the arrow lands. + * `/js arrows.lightning(self)` - lightning strikes where the arrow lands. + * `/js arrows.teleport(self)` - makes player teleport to where arrow has landed. + * `/js arrows.flourish(self)` - makes a tree grow where the arrow lands. + * `/js arrows.explosive(self)` - makes arrows explode. + * `/js arrows.normal(self)` sets arrow type to normal. + * `/js arrows.sign(self)` turns a targeted sign into an Arrows menu + +All of the above functions can take an optional player object or name +as a parameter. For example: `/js arrows.explosive('player23')` makes +player23's arrows explosive. + +***/ +var Drone = require('drone'), + teleport = require('teleport'), + signs = require('signs'), + fireworks = require('fireworks'), + utils = require('utils'), + bkArrow = org.bukkit.entity.Arrow, + bkPlayer = org.bukkit.entity.Player, + EXPLOSIVE_YIELD = 2.5, + store = persist('arrows',{ players: { } }), + arrows = {}, + i, + type, + _types = [ 'Normal', 'Explosive', 'Teleport', 'Flourish', 'Lightning', 'Firework' ]; + +exports.arrows = arrows; + + +for ( i = 0; i < _types.length; i++ ) { + type = _types[i].toLowerCase(); + // iife (immediately-invoked function expression) + arrows[ type ] = ( function( n ) { + return function( player ) { + player = utils.player( player ); + if ( player ) { + store.players[ player.name ] = n; + } else { + console.warn('arrows.' + n + ' No player ' + player); + } + }; + } )( i ); +} + +/* + called when the player chooses an arrow option from a menu sign + */ +var _onMenuChoice = function( event ) { + store.players[ event.player.name ] = event.number; +}; + +var convertToArrowSign = signs.menu( 'Arrow', _types, _onMenuChoice ); + +/* + turn a sign into a menu of arrow choices + */ +arrows.sign = function( cmdSender ) { + var sign = signs.getTargetedBy( cmdSender ); + if ( !sign ) { + throw new Error( 'You must first look at a sign!' ); + } + return convertToArrowSign( sign, true ); +}; + +/* + event handler called when a projectile hits something + */ +function onBukkitArrowHit( event ) { + var projectile = event.entity, + world = projectile.world, + shooter = projectile.shooter, + fireworkCount = 5, + arrowType; + + function launch(){ + fireworks.firework( projectile.location ); + if ( --fireworkCount ) { + setTimeout( launch, 2000 ); + } + } + if (projectile instanceof bkArrow + && shooter instanceof bkPlayer) { + + arrowType = store.players[ shooter.name ]; + + switch ( arrowType ) { + case 1: + projectile.remove(); + world.createExplosion( projectile.location, EXPLOSIVE_YIELD ); + break; + case 2: + projectile.remove(); + teleport(shooter, projectile.location); + break; + case 3: + projectile.remove(); + new Drone(projectile.location).oak(); + break; + case 4: + projectile.remove(); + world.strikeLightning( projectile.location ); + break; + case 5: + projectile.remove(); + launch(); + break; + } + } +} + +function onCanaryArrowHit( event ) { + var projectile = event.projectile, + world = projectile.world, + shooter = projectile.owner, + fireworkCount = 5, + arrowType, + cmArrow = Packages.net.canarymod.api.entity.Arrow, + cmPlayer = Packages.net.canarymod.api.entity.living.humanoid.Player, + loc = projectile.location, + launch = function( ) { + fireworks.firework( loc); + if ( --fireworkCount ) { + setTimeout( launch, 2000 ); + } + }; + + if (projectile instanceof cmArrow && shooter instanceof cmPlayer) { + + arrowType = store.players[ shooter.name ]; + + switch ( arrowType ) { + case 1: + projectile.destroy(); + world.makeExplosion( shooter, loc, EXPLOSIVE_YIELD, true ); + break; + case 2: + projectile.destroy(); + teleport(shooter, loc); + break; + case 3: + projectile.destroy(); + new Drone( loc ).oak(); + break; + case 4: + projectile.destroy(); + world.makeLightningBolt( loc ); + break; + case 5: + projectile.destroy(); + launch(); + break; + } + } +} +events.projectileHit( __plugin.bukkit ? onBukkitArrowHit : onCanaryArrowHit); diff --git a/server/scriptcraft/plugins/at.js b/server/scriptcraft/plugins/at.js new file mode 100755 index 0000000..f194221 --- /dev/null +++ b/server/scriptcraft/plugins/at.js @@ -0,0 +1,4 @@ +// ensure that the at world-load event handlers are +// registered early in server startup +var at = require('at'); +// nothing more needed. diff --git a/server/scriptcraft/plugins/classroom.js b/server/scriptcraft/plugins/classroom.js new file mode 100755 index 0000000..47f7d45 --- /dev/null +++ b/server/scriptcraft/plugins/classroom.js @@ -0,0 +1,11 @@ +/*global require, exports, command*/ +var cr = require('classroom'); + +command(function classroom( params, sender){ + if (params[0] == 'on'){ + cr.allowScripting(true, sender); + }else { + cr.allowScripting(false, sender); + } +},['on','off']); +exports.classroom = cr; diff --git a/server/scriptcraft/plugins/commando/commando-test.js b/server/scriptcraft/plugins/commando/commando-test.js new file mode 100755 index 0000000..3e535cb --- /dev/null +++ b/server/scriptcraft/plugins/commando/commando-test.js @@ -0,0 +1,26 @@ +/* + A test of the commando plugin. + Adds a new `/js-time` command with 4 possible options: Dawn, Midday, Dusk, Midnight +*/ +if (__plugin.canary){ + console.warn('commando-test not yet supported in CanaryMod'); + return; +} +var commando = require('./commando').commando, + times = ['Dawn','Midday','Dusk','Midnight']; + +commando( 'js-time' , function( params, sender ) { + var time = ''+params[0].toLowerCase(), + i = 0; + if ( sender.location ) { + for ( ; i < 4; i++ ) { + if ( times.toLowerCase() == time ) { + sender.location.world.setTime( i * 6000 ); + break; + } + } + } else { + echo( sender, 'This command only works in-world'); + } + +},times); diff --git a/server/scriptcraft/plugins/commando/commando.js b/server/scriptcraft/plugins/commando/commando.js new file mode 100755 index 0000000..331c99c --- /dev/null +++ b/server/scriptcraft/plugins/commando/commando.js @@ -0,0 +1,122 @@ +/************************************************************************* +## Commando Plugin + +### Description + +commando is a plugin which can be used to add completely new commands +to Minecraft. Normally ScriptCraft only allows for provision of new +commands as extensions to the jsp command. For example, to create a +new simple command for use by all players... + + /js command('hi', function(args,player){ echo( player, 'Hi ' + player.name); }); + +... then players can use this command by typing... + + /jsp hi + +... A couple of ScriptCraft users have asked for the ability to take +this a step further and allow the global command namespace to be +populated so that when a developer creates a new command using the +'command' function, then the command is added to the global command +namespace so that players can use it simply like this... + + /hi + +... There are good reasons why ScriptCraft's core `command()` function +does not do this. Polluting the global namespace with commands would +make ScriptCraft a bad citizen in that Plugins should be able to work +together in the same server and - as much as possible - not step on +each others' toes. The CraftBukkit team have very good reasons for +forcing Plugins to declare their commands in the plugin.yml +configuration file. It makes approving plugins easier and ensures that +craftbukkit plugins behave well together. While it is possible to +override other plugins' commands, the CraftBukkit team do not +recommend this. However, as ScriptCraft users have suggested, it +should be at the discretion of server administrators as to when +overriding or adding new commands to the global namespace is good. + +So this is where `commando()` comes in. It uses the exact same +signature as the core `command()` function but will also make the +command accessible without the `jsp` prefix so instead of having to +type `/jsp hi` for the above command example, players simply type +`/hi` . This functionality is provided as a plugin rather than as part +of the ScriptCraft core. + +### Example hi-command.js + + var commando = require('../commando'); + commando('hi', function(args,player){ + echo( player, 'Hi ' + player.name); + }); + +...Displays a greeting to any player who issues the `/hi` command. + +### Example - timeofday-command.js + + var times = {Dawn: 0, Midday: 6000, Dusk: 12000, Midnight:18000}; + commando('timeofday', function(params,player){ + player.location.world.setTime(times[params[0]]); + }, + ['Dawn','Midday','Dusk','Midnight']); + +... changes the time of day using a new `/timeofday` command (options are Dawn, Midday, Dusk, Midnight) + +### Caveats + +Since commands registered using commando are really just appendages to +the `/jsp` command and are not actually registered globally (it just +looks like that to the player), you won't be able to avail of tab +completion for the command itself or its parameters (unless you go the +traditional route of adding the `jsp` prefix). This plugin uses the +[PlayerCommandPreprocessEvent][pcppevt] which allows plugins to +intercepts all commands and inject their own commands instead. If +anyone reading this knows of a better way to programmatically add new +global commands for a plugin, please let me know. + +[pcppevt]: http://jd.bukkit.org/dev/apidocs/org/bukkit/event/player/PlayerCommandPreprocessEvent.html + +***/ +if (__plugin.canary){ + console.warn('commando plugin is not yet supported in CanaryMod'); + return; +} +var commands = {}; + +exports.commando = function( name, func, options, intercepts ) { + var result = command( name, func, options, intercepts ); + commands[name] = result; + return result; +}; + +events.playerCommandPreprocess( function( evt ) { + var msg = '' + evt.message; + var parts = msg.match( /^\/([^\s]+)/ ); + if ( !parts ) { + return; + } + if ( parts.length < 2 ) { + return; + } + var command = parts[1]; + if ( commands[command] ) { + evt.message = '/jsp ' + msg.replace( /^\//, '' ); + } +} ); +events.serverCommand( function( evt ) { + var msg = '' + evt.command; + var parts = msg.match( /^\/*([^\s]+)/ ); + if ( !parts ) { + return; + } + if ( parts.length < 2 ) { + return; + } + var command = parts[1]; + if ( commands[ command ] ) { + var newCmd = 'jsp ' + msg.replace( /^\//, '' ); + if ( config.verbose ) { + console.log( 'Redirecting to : %s', newCmd ); + } + evt.command = newCmd; + } +}); diff --git a/server/scriptcraft/plugins/drone/contrib/castle.js b/server/scriptcraft/plugins/drone/contrib/castle.js new file mode 100755 index 0000000..3bb3f18 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/castle.js @@ -0,0 +1,80 @@ +'use strict'; +/*global require */ +var Drone = require('drone'), + blocks = require('blocks'); +/************************************************************************ +### Drone.castle() method + +Creates a Castle. A castle is just a big wide fort with 4 taller forts at each corner. +See also Drone.fort() method. + +#### Parameters + + * side - How many blocks wide and long the castle will be (default: 24. Must be greater than 19) + * height - How tall the castle will be (default: 10. Must be geater than 7) + +#### Example + +At the in-game prompt you can create a castle by looking at a block and typing: + +```javascript +/js castle() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the castle() method. + +```javascript +var d = new Drone(player); +d.castle(); +``` +![castle example](img/castleex1.png) + +***/ +function castle( side, height ) { + // + // use sensible default parameter values + // if no parameters are supplied + // + if ( typeof side == 'undefined' ) + side = 24; + if ( typeof height == 'undefined' ) + height = 10; + if ( height < 8 || side < 20 ) + throw new java.lang.RuntimeException('Castles must be at least 20 wide X 8 tall'); + // + // how big the towers at each corner will be... + // + var towerSide = 10; + var towerHeight = height+4; + + // + // the main castle building will be front and right of the first tower + // + this + .chkpt('castle') + .fwd( towerSide / 2 ) + .right( towerSide / 2 ) + .fort( side, height ) + .move( 'castle' ); + // + // now place 4 towers at each corner (each tower is another fort) + // + for ( var corner = 0; corner < 4; corner++ ) { + // construct a 'tower' fort + this + .fort( towerSide, towerHeight ) + .chkpt('tower-' + corner) + .fwd( towerSide - 1 ) + .right( towerSide - 3 ) + .up( towerHeight - 5 ) // create 2 doorways from main castle rampart into each tower + .box( blocks.air, 1, 2, 1 ) + .back( 2 ) + .right( 2 ) + .box( blocks.air, 1, 2, 1 ) + .move( 'tower-' + corner) + .fwd( side + towerSide - 1) // move forward the length of the castle then turn right + .turn(); + } + this.move('castle'); +} +Drone.extend(castle); diff --git a/server/scriptcraft/plugins/drone/contrib/chessboard.js b/server/scriptcraft/plugins/drone/contrib/chessboard.js new file mode 100755 index 0000000..9088ef0 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/chessboard.js @@ -0,0 +1,60 @@ +'use strict'; +/*global require */ +var Drone = require('drone'), + blocks = require('blocks'); +/************************************************************************ +### Drone.chessboard() method + +Creates a tile pattern of given block types and size + +#### Parameters + + * whiteBlock - (optional: default blocks.wool.white) + * blackBlock - (optional: default blocks.wool.black) + * width - width of the chessboard + * length - length of the chessboard + +#### Example + +At the in-game prompt you can create a chessboard by looking at a block and typing: + +```javascript +/js chessboard() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the chessboard() method. + +```javascript +var d = new Drone(player); +d.chessboard(); +``` +![chessboard example](img/chessboardex1.png) + +***/ +Drone.extend('chessboard', function( whiteBlock, blackBlock, width, depth ) { + var i, + j, + block; + + + if ( typeof whiteBlock == 'undefined' ) { + whiteBlock = blocks.wool.white; + } + if ( typeof blackBlock == 'undefined' ) { + blackBlock = blocks.wool.black; + } + if ( typeof width == 'undefined' ) { + width = 8; + } + if ( typeof depth == 'undefined' ) { + depth = width; + } + var squares = [ blackBlock, whiteBlock ]; + + this.chkpt('chessboard-start'); + for ( i = 0; i < depth; i++ ) { + this.boxa( squares, width, 1, 1).fwd(); + squares = squares.reverse(); + } + this.move('chessboard-start'); +}); diff --git a/server/scriptcraft/plugins/drone/contrib/cottage.js b/server/scriptcraft/plugins/drone/contrib/cottage.js new file mode 100755 index 0000000..b3a6405 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/cottage.js @@ -0,0 +1,160 @@ +'use strict'; +/*global require */ +var Drone = require('drone'), + blocks = require('blocks'); +/************************************************************************ +### Drone.cottage() method + +Creates a simple but cosy dwelling. + +#### Example + +At the in-game prompt you can create a cottage by looking at a block and typing: + +```javascript +/js cottage() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the cottage() method. + +```javascript +var d = new Drone(player); +d.cottage(); +``` +![cottage example](img/cottageex1.png) + +***/ +function cottage( ) { + this + .chkpt('cottage') + .down() + .box(blocks.birch, 7, 1, 6) // birch wood floor + .up() + .box(blocks.air, 7, 5, 6) // clear area first + .box0( blocks.moss_stone, 7, 2, 6) // 4 walls + .right(3) + .door() // door front and center + .up(1) + .left(2) + .box( blocks.glass_pane ) // windows to left and right + .right(4) + .box( blocks.glass_pane ) + .left(5) + .up() + .prism0( blocks.stairs.oak, 7, 6) // add a roof + .down() + .right(4) + .back() + .wallsign(['Home','Sweet','Home']) + .fwd() + .move('cottage') + .right(3) + .fwd(4) + .up() + .hangtorch() // place a torch on wall + .move('cottage') + .right() + .fwd(3) + .bed() // place a bed against left wall + .fwd() + .right(4) + .box(blocks.furnace) // place a furnace against right wall + .move('cottage') + ; +} +/************************************************************************ +### Drone.cottage_road() method + +Creates a tree-lined avenue with cottages on both sides. + +#### Parameters + + * numberOfCottages: The number of cottages to build in total (optional: default 6) + +#### Example + +At the in-game prompt you can create a cottage road by looking at a block and typing: + +```javascript +/js cottage_road() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the cottage_road() method. + +```javascript +var d = new Drone(player); +d.cottage_road(); +``` +![cottage_road example](img/cottageroadex1.png) + +***/ + +// +// a more complex script that builds an tree-lined avenue with +// cottages on both sides. +// +function cottage_road( numberCottages ) { + if (typeof numberCottages == 'undefined'){ + numberCottages = 6; + } + var i=0, distanceBetweenTrees = 11; + // + // step 1 build the road. + // + var cottagesPerSide = Math.floor(numberCottages/2); + this + // make sure the drone's state is saved. + .chkpt('cottage_road') + // build the road + .box( blocks.double_slab.stone, 3, 1, cottagesPerSide * ( distanceBetweenTrees + 1 ) ) + .up() + // now centered in middle of road + .right() + // will be returning to this position later + .chkpt('cottage_road_cr'); + + // + // step 2 line the road with trees + // + for ( ; i < cottagesPerSide+1;i++ ) { + this + .left(5) + .oak() + .right(10) + .oak() + .left(5) // return to middle of road + .fwd( distanceBetweenTrees + 1 ); // move forward. + } + this + .move('cottage_road_cr') + .back(6); // move back 1/2 the distance between trees + + // this function builds a path leading to a cottage. + function pathAndCottage( drone ) { + drone + .down() + .box(blocks.double_slab.stone, 1, 1, 5) + .fwd(5) + .left(3) + .up() + .cottage(); + return drone; + }; + // + // step 3 build cottages on each side + // + for ( i = 0; i < cottagesPerSide; i++ ) { + this + .fwd( distanceBetweenTrees + 1 ) + .chkpt('r'+i); + // build cottage on left + pathAndCottage( this.turn(3) ).move( 'r' + i ); + // build cottage on right + pathAndCottage( this.turn() ).move( 'r' + i ); + } + // return drone to where it was at start of function + this.move('cottage_road'); +} +Drone.extend(cottage_road); +Drone.extend(cottage); + diff --git a/server/scriptcraft/plugins/drone/contrib/dancefloor.js b/server/scriptcraft/plugins/drone/contrib/dancefloor.js new file mode 100755 index 0000000..10091d8 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/dancefloor.js @@ -0,0 +1,74 @@ +'use strict'; +/*global require, clearInterval, setInterval*/ +var Drone = require('drone'), + blocks = require('blocks'), + SECOND = 1000; +/************************************************************************ +### Drone.dancefloor() method +Create an animated dance floor of colored tiles some of which emit light. +The tiles change color every second creating a strobe-lit dance-floor effect. +See it in action here [http://www.youtube.com/watch?v=UEooBt6NTFo][ytdance] + +#### Parameters + + * width - how wide the dancefloor should be (optional: default 5) + * length - how long the dancefloor should be (optional: default 5) + * duration - the time duration for which the lights should change (optional: default 30 seconds) + +#### Example + +At the in-game prompt you can create a dancefloor by looking at a block and typing: + +```javascript +/js dancefloor() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the dancefloor() method. + +```javascript +var d = new Drone(player); +d.dancefloor(); +``` + +[ytdance]: http://www.youtube.com/watch?v=UEooBt6NTFo +![dancefloor example](img/dancefloorex1.png) +***/ + + +// +function dancefloor(width, length, duration) +{ + if (typeof width == 'undefined') + width = 5; + if (typeof length == 'undefined') + length = width; + if (typeof duration === 'undefined'){ + duration = 30; + } + // + // create a separate Drone object to lay down disco tiles + // + var disco = new Drone(this.x, this.y, this.z, this.dir, this.world); + // + // under-floor lighting + // + disco + .down() + .box( blocks.glowstone, width, 1, length) + .up(); + + // + // strobe gets called in a java thread - disco only lasts 30 seconds. + // + var task = null; + var strobe = function() { + disco.rand(blocks.rainbow, width, 1, length); + duration--; + if ( duration == 0 ){ + // turn off the lights + clearInterval(task); + } + }; + task = setInterval( strobe, 1 * SECOND); +} +Drone.extend( dancefloor ); diff --git a/server/scriptcraft/plugins/drone/contrib/fort.js b/server/scriptcraft/plugins/drone/contrib/fort.js new file mode 100755 index 0000000..0e41346 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/fort.js @@ -0,0 +1,126 @@ +'use strict'; +/*global require */ +var Drone = require('drone'), + blocks = require('blocks'); +/************************************************************************ +### Drone.fort() method + +Constructs a medieval fort. + +#### Parameters + + * side - How many blocks whide and long the fort will be (default: 18 . Must be greater than 9) + * height - How tall the fort will be (default: 6 . Must be greater than 3) + +#### Example + +At the in-game prompt you can create a fort by looking at a block and typing: + +```javascript +/js fort() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the fort() method. + +```javascript +var d = new Drone(player); +d.fort(); +``` +![fort example](img/fortex1.png) + +***/ +function fort( side, height ) { + var turret, + i, + torch; + + if ( typeof side == 'undefined' ) { + side = 18; + } + if ( typeof height == 'undefined' ) { + height = 6; + } + // make sure side is even + if ( side % 2 ) { + side++; + } + var battlementWidth = 3; + if ( side <= 12 ) { + battlementWidth = 2; + } + if ( height < 4 || side < 10 ) { + throw new java.lang.RuntimeException('Forts must be at least 10 wide X 4 tall'); + } + // + // build walls. + // + this + .chkpt('fort') + .down() + .chessboard( blocks.wool.black, blocks.wool.white, side) + .up() + .box0( blocks.brick.stone, side, height - 1, side) + .up(height-1); + // + // build battlements + // + for ( i = 0; i <= 3; i++ ) { + + turret = [ + blocks.stairs.stone , + blocks.stairs.stone + ':'+ Drone.PLAYER_STAIRS_FACING[ (this.dir + 2) % 4 ] + ]; + this + .box( blocks.brick.stone ) // solid brick corners + .up() + .box(blocks.torch) + .down() // light a torch on each corner + .fwd() + .boxa( turret, 1, 1, side-2) + .fwd( side-2 ) + .turn(); + } + // + // build battlement's floor + // + this + .move('fort') + .up(height-2) + .fwd() + .right(); + + for ( i = 0; i < battlementWidth; i++ ) { + var bside = side - ( 2 + (i * 2) ); + this + .box0( blocks.slab.oak, bside, 1, bside) + .fwd() + .right(); + } + // + // add door + // + torch = blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[this.dir]; + this + .move('fort') + .right( ( side / 2 ) - 1 ) + .door2() // double doors + .back() + .left() + .up() + .box( torch ) // left torch + .right( 3 ) + .box( torch ); // right torch + // + // add ladder up to battlements + // + this + .move('fort') + .right( ( side / 2 ) - 3 ) + .fwd() // move inside fort + .turn( 2 ) + .box( blocks.air, 1, height - 1, 1) + .ladder( height - 1 ) + .move( 'fort' ); +} +Drone.extend(fort); + diff --git a/server/scriptcraft/plugins/drone/contrib/hangtorch.js b/server/scriptcraft/plugins/drone/contrib/hangtorch.js new file mode 100755 index 0000000..9aacc66 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/hangtorch.js @@ -0,0 +1,69 @@ +'use strict'; +/*global require, __plugin, org*/ +var Drone = require('drone'), + blocks = require('blocks'); +/************************************************************************ +### Drone.hangtorch() method + +Adds a hanging torch to a wall. This method will try to hang a torch +against a wall. It will traverse backwards until it finds a block +adjacent to air and hang the torch. If it can't find a block next to +air it will log a message in the server. + +#### Example + +At the in-game prompt you can create a hanging torch by looking at a +block and typing: + +```javascript +/js hangtorch() +``` + +Alternatively you can create a new Drone object from a Player or +Location object and call the hangtorch() method. + +```javascript +var d = new Drone(player); +d.hangtorch(); +``` + +***/ +function canHang( block ) { + + if (__plugin.bukkit){ + var bkMaterial = org.bukkit.Material; + if ( block.type.equals(bkMaterial.AIR) || + block.type.equals(bkMaterial.VINE) ) { + return true; + } + } + if (__plugin.canary){ + if (block.typeId == blocks.air || + block.typeId == blocks.vines ) { + return true; + } + } + return false; +} +function hangtorch() { + var torch = blocks.torch + ':' + Drone.PLAYER_TORCH_FACING[this.dir]; + var moves = 0; + var block = this.getBlock(); + + while ( !canHang(block) ){ + + moves++; + this.back(); + if (moves == 10){ + this + .fwd(moves); + console.log('nowhere to hang torch'); + return; + } + block = this.getBlock(); + } + this + .box(torch) + .fwd(moves); +} +Drone.extend(hangtorch); diff --git a/server/scriptcraft/plugins/drone/contrib/lcd-clock.js b/server/scriptcraft/plugins/drone/contrib/lcd-clock.js new file mode 100755 index 0000000..300b844 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/lcd-clock.js @@ -0,0 +1,105 @@ +'use strict'; +/*global require, setInterval, clearInterval, __plugin, exports*/ +/************************************************************************* +### Drone.lcdclock() method. + +Constructs a large LCD Clock. The clock will display the current time of day. +The clock can be stopped by calling the stopLCD() method of the Drone which created the clock. + +#### Parameters + + * foregroundBlock (Optional - default is blocks.glowstone) + * backgroundBlock (Optional - default is blocks.wool.black) + * borderBlock (Optional - a border around the LCD display - default none) + +#### Example + +At the in-game prompt you can create a LCD clock by looking at a block and typing: + +```javascript +/js var clock = lcdclock() +/js clock.stopLCD() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the lcdclock() method. + +```javascript +var d = new Drone(player); +d.lcdclock(); +d.stopLCD(); +``` +![lcdclock example](img/lcdclockex1.png) +***/ +var blocks = require('blocks'), + utils = require('utils'), + Drone = require('drone'); + +function lcdclock(fgColor, bgColor, border){ + var drone = this; + var lastSecs = [0,0,0,0], + world = drone.world, + intervalId = -1; + + function update(secs) { + var digits = [0,0,0,0], + s = secs % 60, + m = (secs - s) / 60; + digits[3] = s%10; + digits[2] = (s-digits[3])/10; + digits[1] = m%10; + digits[0] = (m-digits[1])/10; + // + // updating all 4 digits each time is expensive + // only update digits which have changed (in most cases - just 1) + // + if (digits[3] != lastSecs[3]){ + drone + .right(14) + .blocktype(''+digits[3],fgColor,bgColor, true) + .left(14); + } + if (digits[2] != lastSecs[2]){ + drone + .right(10) + .blocktype(''+digits[2],fgColor,bgColor, true) + .left(10); + } + if (digits[1] != lastSecs[1]){ + drone + .right(4) + .blocktype(''+digits[1], fgColor, bgColor, true) + .left(4); + } + if (digits[0] != lastSecs[0]){ + drone + .blocktype(''+digits[0], fgColor, bgColor, true); + } + lastSecs[0] = digits[0]; + lastSecs[1] = digits[1]; + lastSecs[2] = digits[2]; + lastSecs[3] = digits[3]; + + } + if ( typeof bgColor == 'undefined' ) { + bgColor = blocks.wool.black; + } + if ( typeof fgColor == 'undefined' ) { + fgColor = blocks.glowstone ; + } + if ( border ) { + drone.box(border,21,9,1); + drone.up().right(); + } + drone.blocktype('00:00', fgColor, bgColor, true); + + function tick() { + var timeOfDayInMins = utils.time24(world); + update( timeOfDayInMins ); + } + intervalId = setInterval(tick, 800); + this.stopLCD = function(){ + clearInterval(intervalId); + }; +} + +Drone.extend(lcdclock); diff --git a/server/scriptcraft/plugins/drone/contrib/logo.js b/server/scriptcraft/plugins/drone/contrib/logo.js new file mode 100755 index 0000000..c633472 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/logo.js @@ -0,0 +1,242 @@ +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); +/************************************************************************ +### Drone.logojs() method + +Constructs a large Javascript Logo (black JS on Yellow background) +See: https://raw.github.com/voodootikigod/logo.js/master/js.png + +#### Parameters + + * foregroundBlock (Optional - default is blocks.wool.gray) + * backgroundBlock (Optional - default is blocks.gold) + +***/ +function logojs(fg, bg) { + + // foreground defaults to gray wool + if (typeof fg == "undefined") + fg = blocks.wool.gray; + // background defaults to gold blocks + if (typeof bg == "undefined") + bg = blocks.gold; + + // Draw the sqaure + this + .chkpt('logojs-start') + .up() + .box(bg, 100, 100, 1); + + // Draw the J, starting with the hook + this + .right(30) + .up(13) + .box(fg) + .right() + .down() + .box(fg, 1, 3, 1) + .right() + .down() + .box(fg, 1, 5, 1) + .right() + .down() + .box(fg, 1, 7, 1) + .right() + .box(fg, 1, 8, 1) + .right() + .down() + .box(fg, 1, 10, 1) + .right() + .box(fg, 1, 9, 1) + .right() + .box(fg, 1, 8, 1) + .right() + .down() + .box(fg, 2, 8, 1) + .right(2) + .box(fg, 4, 7, 1) + .right(4) + .box(fg, 1, 8, 1) + .right() + .box(fg, 1, 9, 1) + .right() + .up() + .box(fg, 3, 10, 1) + .right(3) + .up() + .box(fg, 2, 9, 1) + .right(2) + .up() + .box(fg, 2, 8, 1) + .right(2) + .up() + .box(fg, 1, 7, 1) + .right() + .up() + .box(fg, 1, 6, 1) + .right() + .up() + .box(fg, 1, 5, 1) + .right() + .up(2) + .box(fg, 1, 3, 1) + .left(9) + .up(3) + .box(fg, 10, 31, 1) + + // Draw the S + // It's drawn in three strokes from bottom to top. Look for when + // it switches from .right() to .left() then back again + + // move to starting point for S + .right(22).down(6) + // stroke 1 + .box(fg) + .right().down() + .box(fg, 1, 3, 1) + .right().down() + .box(fg, 1, 5, 1) + .right().down() + .box(fg, 1, 7, 1) + .right() + .box(fg, 1, 8, 1) + .right().down() + .box(fg, 1, 10, 1) + .right() + .box(fg, 1, 9, 1) + .right() + .box(fg, 1, 8, 1) + .right().down() + .box(fg, 2, 8, 1) + .right(2) + .box(fg, 4, 7, 1) + .right(4) + .box(fg, 2, 8, 1) + .right(2) + .box(fg, 1, 9, 1) + .right().up() + .box(fg, 1, 9, 1) + .right() + .box(fg, 1, 10, 1) + .right() + .box(fg, 1, 22, 1) + .right().up() + .box(fg, 2, 20, 1) + .right().up() + .box(fg, 1, 18, 1) + .right().up() + .box(fg, 1, 17, 1) + .right().up() + .box(fg, 1, 15, 1) + .right().up() + .box(fg, 1, 13, 1) + .right().up(2) + .box(fg, 1, 9, 1) + .right().up(2) + .box(fg, 1, 5, 1) + // stroke 2 + .left(8).up(4) + .box(fg, 1, 9, 1) + .left().up() + .box(fg, 1, 9, 1) + .left().up() + .box(fg, 1, 8, 1) + .left(2).up() + .box(fg, 2, 8, 1) + .left(2).up() + .box(fg, 2, 7, 1) + .left(2).up() + .box(fg, 2, 7, 1) + .left() + .box(fg, 1, 8, 1) + .left().up() + .box(fg, 1, 8, 1) + .left() + .box(fg, 1, 9, 1) + .left(2).up() + .box(fg, 2, 19, 1) + .left().up() + .box(fg, 1, 17, 1) + .left() + .box(fg, 1, 16, 1) + .left().up() + .box(fg, 1, 14, 1) + .left().up(2) + .box(fg, 1, 10, 1) + .left().up(2) + .box(fg, 1, 6, 1) + // stroke 3 + .right(7).up(6) + .box(fg, 1, 8, 1) + .right().up() + .box(fg, 1, 7, 1) + .right().up() + .box(fg, 2, 7, 1) + .right(2).up() + .box(fg, 4, 6, 1) + .right(4).down() + .box(fg, 2, 7, 1) + .right().down() + .box(fg, 1, 8, 1) + .right() + .box(fg, 1, 7, 1) + .right().down() + .box(fg, 1, 8, 1) + .right().down() + .box(fg, 1, 9, 1) + .right().down() + .box(fg, 1, 9, 1) + .right().up() + .box(fg, 1, 8, 1) + .right().up() + .box(fg, 1, 6, 1) + .right().up() + .box(fg, 1, 5, 1) + .right().up() + .box(fg, 1, 3, 1) + .right().up() + .box(fg); + + this.move('logojs-start'); + + return this; +} +// +// Makes a cube of JS logos! +// This is a wrapper for logojs() so look at its docs +// +// Until the drone can rotate on its Z axis we can't +// use logojs() to create top/bottom sides of cube. +// +function logojscube(fg, bg) { + + this.chkpt('jscube-start') + .logojs(fg, bg); + + this.move('jscube-start') + .right(100) + .turn(3) + .logojs(fg, bg); + + this.move('jscube-start') + .right(100) + .turn(3) + .right(100) + .turn(3) + .logojs(fg, bg); + + this.move('jscube-start') + .right(100) + .turn(3) + .right(100) + .turn(3) + .right(100) + .turn(3) + .logojs(fg, bg); + + return this; +} +Drone.extend( logojs ); +Drone.extend( logojscube ); diff --git a/server/scriptcraft/plugins/drone/contrib/mazegen.js b/server/scriptcraft/plugins/drone/contrib/mazegen.js new file mode 100755 index 0000000..1ff4a1f --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/mazegen.js @@ -0,0 +1,146 @@ +'use strict'; +/*global require*/ +/************************************************************************ +### Drone.maze() method + +Maze generation based on http://rosettacode.org/wiki/Maze_generation#JavaScript + +#### Parameters + + * width (optional - default 10) + * length (optional - default 10) + +#### Example + +At the in-game prompt you can create a maze by looking at a block and typing: + +```javascript +/js maze() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the maze() method. + +```javascript +var d = new Drone(player); +d.maze(); +``` +![maze example](img/mazeex1.png) + +***/ +var Drone = require('drone'), + blocks = require('blocks'); + +// User-facing code starts here +// Example: Try /js maze(5,7) +Drone.extend( function maze( width, length ) { + if (typeof width === 'undefined'){ + width = 10; + } + if (typeof length === 'undefined'){ + length = 10; + } + var m = maze_make(width, length); + if (m.x > 0 && m.y > 0) { + maze_draw(maze_display(m), this); + } +} ); +// +// Implementation +// +function maze_make(x,y) { + var n=x*y-1; + if (n<0) { + console.log ("illegal maze dimensions"); + return ({x: 0, y: 0}); + } + var horiz=[]; + var j; + for ( j = 0; j0 && j0 && (j != here[0]+1 || k != here[1]+1)); + } + while (00 && m.verti[j/2-1][Math.floor(k/4)]) + line[k]= ' '; + else + line[k]= '-'; + else + for (var k=0; k0 && m.horiz[(j-1)/2][k/4-1]) + line[k]= ' '; + else + line[k]= '|'; + else + line[k]= ' '; + if (0 == j) line[1]= line[2]= line[3]= ' '; + if (m.x*2-1 == j) line[4*m.y]= ' '; + text.push(line.join('')+' \r\n'); // TWEAKED: space added to get an even number of columns + } + return text.join(''); +} + +// ScriptCraft stuff starts here +// Helper function to parse the ASCII art into Drone actions +// You might also consider creating a new maze_display but for now this will do the work +function maze_draw(maze_string, d) { + // d is the Drone to use + d.chkpt('maze-start'); + for (var j = 0; j < maze_string.length; j += 2) { + switch(maze_string.substr(j, 2)) { + case ' ': + d.box(0).fwd(); // Make sure to empty this position + break; + case '\r\n': + d.move('maze-start'); + d.right().chkpt('maze-start'); + break; + default: // '+ ', '+-', '--', '| ' + if (j == 0) { + d.box(blocks.glowstone,1,2,1); // highlight the maze entry and exit + } else if (j == maze_string.length - 4) { + d.box(blocks.glass,1,2,1); + } else { + d.box(blocks.oak,1,2,1); + } + d.fwd(); + } + } +} diff --git a/server/scriptcraft/plugins/drone/contrib/rainbow.js b/server/scriptcraft/plugins/drone/contrib/rainbow.js new file mode 100755 index 0000000..25a6445 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/rainbow.js @@ -0,0 +1,59 @@ +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); + +/************************************************************************ +### Drone.rainbow() method + +Creates a Rainbow. + +#### Parameters + + * radius (optional - default:18) - The radius of the rainbow + +#### Example + +At the in-game prompt you can create a rainbow by looking at a block and typing: +```javascript +/js rainbow() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the rainbow() method. + +```javascript +var d = new Drone(player); +d.rainbow(30); +``` + +![rainbow example](img/rainbowex1.png) + +***/ +function rainbow( radius ) { + var i, + colors, + bm; + + if ( typeof radius == "undefined" ) { + radius = 18; + } + + this.chkpt('rainbow'); + this.down(radius); + // copy blocks.rainbow and add air at end (to compensate for strokewidth) + colors = blocks.rainbow.slice(0); + colors.push(blocks.air); + for ( i = 0; i < colors.length; i++ ) { + bm = this.getBlockIdAndMeta( colors[i] ); + this.arc({ + blockType: bm[0], + meta: bm[1], + radius: radius-i, + strokeWidth: 2, + quadrants: {topright: true, + topleft: true}, + orientation: 'vertical'}).right().up(); + } + return this.move('rainbow'); +} +Drone.extend(rainbow); diff --git a/server/scriptcraft/plugins/drone/contrib/redstonewire.js b/server/scriptcraft/plugins/drone/contrib/redstonewire.js new file mode 100755 index 0000000..fa74a62 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/redstonewire.js @@ -0,0 +1,110 @@ +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); + +// +// usage: +// [1] to place a new block with redstone wire on it (block on bottom, redstone on top) +// /js wireblock(blocks.sandstone); +// +// [2] to drop wire on to an existing block +// /js wire() +// +// [3] to place a (redstone) torch on a new block +// /js torchblock(blocks.sandstone) +// +// [4] to place a repeater on a new block +// /js repeaterblock(blocks.sandstone) +// +// [5] To create a long redstone wire (with necessary repeaters, powererd by a single torch) +// /js wirestraight(blocks.sandstone, distance) +// +// [6] To create a 'road' with redstone torches and wire lining each side +// /js redstoneroad(blocks.stone, blocks.sandstone, 25) + +Drone.extend('wireblock',function(blockType) +{ + this.chkpt('wireblock') + .box(blockType,1,2,1) // 2 blocks tall, top block will be wire dropped on lower + .up(); + + this.world.getBlockAt(this.x,this.y,this.z).setTypeId(55); //apply wire + + return this.move('wireblock'); +}); + +Drone.extend('wire',function () +{ + this.chkpt('wire') + .up(); + + this.world.getBlockAt(this.x,this.y,this.z).setTypeId(55); // apply wire + + return this.move('wire'); +}); + +Drone.extend('torchblock', function(blockType) +{ + this.box(blockType,1,2,1) // 2 blocks tall + .up(); + + this.world.getBlockAt(this.x,this.y,this.z).setTypeId(76); // apply torch + + return this.down(); +}); + +Drone.extend('repeaterblock',function(blockType) +{ + this.chkpt('repeaterblock') + .box(blockType,1,2,1) + .up(); + + var block = this.world.getBlockAt(this.x,this.y,this.z); + block.setTypeId(94); // apply repeater + + // redstone repeater dirs: north=0,east=1,south=2,west=3 + var direction = [1,2,3,0][this.dir]; // convert drone dir to repeater dir. + block.setData(direction); + + return this.move('repeaterblock'); +}); + + +Drone.extend('wirestraight',function (blockType,distance) +{ + this.chkpt('wirestraight'); + + this.torchblock(blockType); + this.fwd(); + + for (var i = 1; i < distance; i++) { + if(i % 14 == 0) + { + this.repeaterblock(blockType); + } + else + { + this.wireblock(blockType); + } + + this.fwd(); + }; + + return this.move('wirestraight'); +}); + + +Drone.extend('redstoneroad', function (roadBlockType, redstoneunderBlockType, distance) +{ + return this.down() + .wirestraight(redstoneunderBlockType, distance) + .right() + .box(roadBlockType, 4,1,distance) + .right(4) + .wirestraight(redstoneunderBlockType, distance) + .up(); +}); + + + diff --git a/server/scriptcraft/plugins/drone/contrib/spiral_stairs.js b/server/scriptcraft/plugins/drone/contrib/spiral_stairs.js new file mode 100755 index 0000000..4f9b356 --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/spiral_stairs.js @@ -0,0 +1,52 @@ +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); + +/************************************************************************ +### Drone.spiral_stairs() method + +Constructs a spiral staircase with slabs at each corner. + +#### Parameters + + * stairBlock - The block to use for stairs, should be one of the following... + - 'oak' + - 'spruce' + - 'birch' + - 'jungle' + - 'cobblestone' + - 'brick' + - 'stone' + - 'nether' + - 'sandstone' + - 'quartz' + * flights - The number of flights of stairs to build. + +![Spiral Staircase](img/spiralstair1.png) + +#### Example + +To construct a spiral staircase 5 floors high made of oak... + + spiral_stairs('oak', 5); + +***/ +function spiral_stairs(stairBlock, flights){ + this.chkpt('spiral_stairs'); + + for (var i = 0; i < flights; i++){ + this + .box(blocks.stairs[stairBlock] ) + .up() + .fwd() + .box(blocks.stairs[stairBlock] ) + .up() + .fwd() + .box(blocks.slab[stairBlock]) + .turn() + .fwd(); + } + this.move('spiral_stairs'); +} +Drone.extend(spiral_stairs); diff --git a/server/scriptcraft/plugins/drone/contrib/temple.js b/server/scriptcraft/plugins/drone/contrib/temple.js new file mode 100755 index 0000000..d841b0f --- /dev/null +++ b/server/scriptcraft/plugins/drone/contrib/temple.js @@ -0,0 +1,55 @@ +'use strict'; +/*global require*/ +var Drone = require('drone'), + blocks = require('blocks'); +/************************************************************************ +### Drone.temple() method + +Constructs a mayan temple. + +#### Parameters + + * side - How many blocks wide and long the temple will be (default: 20) + +#### Example + +At the in-game prompt you can create a temple by looking at a block and typing: + +```javascript +/js temple() +``` + +Alternatively you can create a new Drone object from a Player or Location object and call the temple() method. + +```javascript +var d = new Drone(player); +d.temple(); +``` +![temple example](img/templeex1.png) + +***/ +function temple( side ) { + if ( !side ) { + side = 20; + } + this.chkpt('temple'); + + while ( side > 4 ) { + var middle = Math.round( (side-2) / 2 ); + this + .chkpt('temple-corner') + .box( blocks.brick.mossy, side, 1, side ) + .right( middle ) + .box( blocks.stairs.stone ) + .right() + .box( blocks.stairs.stone ) + .move('temple-corner') + .up() + .fwd() + .right(); + side = side - 2; + } + + this.move('temple'); +} +Drone.extend( temple ); diff --git a/server/scriptcraft/plugins/drone/drone.js b/server/scriptcraft/plugins/drone/drone.js new file mode 100755 index 0000000..12c032d --- /dev/null +++ b/server/scriptcraft/plugins/drone/drone.js @@ -0,0 +1,4 @@ +/*global require, exports*/ +var blocks = require('blocks'); +exports.Drone = require('drone'); +exports.blocks = blocks; diff --git a/server/scriptcraft/plugins/examples/example-1-hello-module.js b/server/scriptcraft/plugins/examples/example-1-hello-module.js new file mode 100755 index 0000000..3306704 --- /dev/null +++ b/server/scriptcraft/plugins/examples/example-1-hello-module.js @@ -0,0 +1,30 @@ +/************************************************************************* +## Example Plugin #1 - A simple extension to Minecraft. + +A simple minecraft plugin. The most basic module. + +### Usage: + +At the in-game prompt type ... + + /js hello(self) + +... and a message `Hello {player-name}` will appear (where + {player-name} is replaced by your own name). + +This example demonstrates the basics of adding new functionality which +is only usable by server operators or users with the +scriptcraft.evaluate permission. By default, only ops are granted this +permission. + +The `hello` function below is only usable by players with the scriptcraft.evaluate +permission since it relies on the `/js` command to execute. + + exports.hello = function(player){ + echo( player, 'Hello ' + player.name); + }; + +***/ +exports.hello = function( player ) { + echo( player, 'Hello ' + player.name ); +}; diff --git a/server/scriptcraft/plugins/examples/example-2-hello-command.js b/server/scriptcraft/plugins/examples/example-2-hello-command.js new file mode 100755 index 0000000..1ef6b20 --- /dev/null +++ b/server/scriptcraft/plugins/examples/example-2-hello-command.js @@ -0,0 +1,32 @@ +/************************************************************************* +## Example Plugin #2 - Making extensions available for all players. + +A simple minecraft plugin. Commands for other players. + +### Usage: + +At the in-game prompt type ... + + /jsp hello + +... and a message `Hello {player-name}` will appear (where {player-name} is +replaced by your own name). + +This example demonstrates the basics of adding new functionality +which is usable all players or those with the scriptcraft.proxy +permission. By default, all players are granted this permission. + +This differs from example 1 in that a new 'jsp ' command extension +is defined. Since all players can use the `jsp` command, all players +can use the new extension. Unlike the previous example, the `jsp hello` +command does not evaluate javascript code so this command is much more secure. + + command('hello', function (parameters, player) { + echo( player, 'Hello ' + player.name); + }); + +***/ + +command( 'hello', function( parameters, player ) { + echo( player, 'Hello ' + player.name ); +}); diff --git a/server/scriptcraft/plugins/examples/example-3-hello-ops-only.js b/server/scriptcraft/plugins/examples/example-3-hello-ops-only.js new file mode 100755 index 0000000..5c7893a --- /dev/null +++ b/server/scriptcraft/plugins/examples/example-3-hello-ops-only.js @@ -0,0 +1,42 @@ +/************************************************************************* +## Example Plugin #3 - Limiting use of commands to operators only. + +A simple minecraft plugin. Commands for operators only. + +### Usage: + +At the in-game prompt type ... + + /jsp op-hello + +... and a message `Hello {player-name}` will appear (where {player-name} is +replaced by your own name). + +This example demonstrates the basics of adding new functionality +which is usable all players or those with the scriptcraft.proxy +permission. By default, all players are granted this permission. In +this command though, the function checks to see if the player is an +operator and if they aren't will return immediately. + +This differs from example 2 in that the function will only print a +message for operators. + + command('op-hello', function (parameters, player) { + if ( !isOp(player) ){ + echo( player, 'Only operators can do this.'); + return; + } + echo( player, 'Hello ' + player.name); + }); +***/ + +command( 'op-hello', function( parameters, player ) { + /* + this is how you limit based on player privileges + */ + if ( !isOp(player) ) { + echo( player, 'Only operators can do this.' ); + return; + } + echo( player, 'Hello ' + player.name ); +}); diff --git a/server/scriptcraft/plugins/examples/example-4-hello-parameters.js b/server/scriptcraft/plugins/examples/example-4-hello-parameters.js new file mode 100755 index 0000000..ba01adc --- /dev/null +++ b/server/scriptcraft/plugins/examples/example-4-hello-parameters.js @@ -0,0 +1,40 @@ +/************************************************************************* +## Example Plugin #4 - Using parameters in commands. + +A simple minecraft plugin. Handling parameters. + +### Usage: + +At the in-game prompt type ... + + /jsp hello-params Hi + /jsp hello-params Saludos + /jsp hello-params Greetings + +... and a message `Hi {player-name}` or `Saludos {player-name}` etc +will appear (where {player-name} is replaced by your own name). + +This example demonstrates adding and using parameters in commands. + +This differs from example 3 in that the greeting can be changed from +a fixed 'Hello ' to anything you like by passing a parameter. + + command( 'hello-params', function ( parameters, player ) { + var salutation = parameters[0] ; + echo( player, salutation + ' ' + player.name ); + }); + +***/ + +command('hello-params', function( parameters, player ) { + /* + parameters is an array (or list) of strings. parameters[0] + refers to the first element in the list. Arrays in Javascript + are 0-based. That is, the 1st element is parameters[0], the 2nd + element is parameters[1], the 3rd element is parameters[2] and + so on. In this example, parameters[1] refers to the first word + which appears after `jsp hello-params `. + */ + var salutation = parameters[0] ; + echo( player, salutation + ' ' + player.name ); +}); diff --git a/server/scriptcraft/plugins/examples/example-5-hello-using-module.js b/server/scriptcraft/plugins/examples/example-5-hello-using-module.js new file mode 100755 index 0000000..aba9b62 --- /dev/null +++ b/server/scriptcraft/plugins/examples/example-5-hello-using-module.js @@ -0,0 +1,41 @@ +/************************************************************************* +## Example Plugin #5 - Re-use - Using your own and others modules. + +A simple minecraft plugin. Using Modules. + +### Usage: + +At the in-game prompt type ... + + /jsp hello-module + +... and a message `Hello {player-name}` will appear (where {player-name} is +replaced by your own name). + +This example demonstrates the use of modules. In +example-1-hello-module.js we created a new javascript module. In +this example, we use that module... + + * We load the module using the `require()` function. Because this + module and the module we require are n the same directory, we + specify `'./example-1-hello-module'` as the path (when loading a + module from the same directory, `./` at the start of the path + indicates that the file should be searched for in the same + directory. + + * We assign the loaded module to a variable (`greetings`) and then + use the module's `hello` method to display the message. + +Source Code... + + var greetings = require('./example-1-hello-module'); + command( 'hello-module', function( parameters, player ) { + greetings.hello( player ); + }); + +***/ +var greetings = require('./example-1-hello-module'); + +command( 'hello-module', function( parameters, player ) { + greetings.hello( player ); +}); diff --git a/server/scriptcraft/plugins/examples/example-6-hello-player.js b/server/scriptcraft/plugins/examples/example-6-hello-player.js new file mode 100755 index 0000000..fd92854 --- /dev/null +++ b/server/scriptcraft/plugins/examples/example-6-hello-player.js @@ -0,0 +1,58 @@ +/************************************************************************* +## Example Plugin #6 - Re-use - Using 'utils' to get Player objects. + +A simple minecraft plugin. Finding players by name. + +### Usage: + +At the in-game prompt type ... + + /jsp hello-byname {player-name} + +... substituting {player-name} with the name of a player currently +online and a message `Hello ...` will be sent to the named +player. + +This example builds on example-5 and also introduces a new concept - +use of shared modules. That is : modules which are not specific to +any one plugin or set of plugins but which can be used by all +plugins. Shared modules should be placed in the +`scriptcraft/modules` directory. + + * The utils module is used. Because the 'utils' module is + located in the modules folder we don't need to specify an exact + path, just 'utils' will do. + + * The `utils.player()` function is used to obtain a player object + matching the player name. Once a player object is obtained, a + message is sent to that player. + +Source Code ... + + var utils = require('utils'); + var greetings = require('./example-1-hello-module'); + + command( 'hello-byname', function( parameters, sender ) { + var playerName = parameters[0]; + var recipient = utils.player( playerName ); + if ( recipient ) { + greetings.hello( recipient ); + } else { + echo( sender, 'Player ' + playerName + ' not found.' ); + } + }); + +***/ + +var utils = require('utils'); +var greetings = require('./example-1-hello-module'); + +command( 'hello-byname', function( parameters, sender ) { + var playerName = parameters[0]; + var recipient = utils.player( playerName ); + if ( recipient ) { + greetings.hello( recipient ); + } else { + echo( sender, 'Player ' + playerName + ' not found.' ); + } +}); diff --git a/server/scriptcraft/plugins/examples/example-7-hello-events.js b/server/scriptcraft/plugins/examples/example-7-hello-events.js new file mode 100755 index 0000000..72ba171 --- /dev/null +++ b/server/scriptcraft/plugins/examples/example-7-hello-events.js @@ -0,0 +1,73 @@ +'use strict'; +/*global events, echo, isOp, __plugin*/ +/************************************************************************* +## Example Plugin #7 - Listening for events, Greet players when they join the game. + +A simple event-driven minecraft plugin. How to handle Events. + +This example demonstrates event-driven programming. The code below +will display the version of ScriptCraft every time an operator joins +the game. This module is notable from previous modules for the +following reasons... + + 1. It does not export any functions or variables. That's fine. Not + all modules need export stuff. Code in this module will be + executed when the module is first loaded. Because it is in the + `/scriptcraft/plugins` directory, it will be loaded automatically + when the server starts up. + + 2. It uses ScriptCraft's `events` module to add a new *Event + Handler*. An *Event Handler* is a function that gets + called whenever a particular *event* happens in the game. The + function defined below will only be executed whenever a player + joins the game. This style of program is sometimes refered to as + *Event-Driven Programming*. + +Adding new *Event Handlers* in ScriptCraft is relatively easy. Use one +of the `events` module's functions to add a new event handler. The +events module has many functions - one for each type of event. Each +function takes a single parameter: + + * The event handling function (also sometimes refered to as a + 'callback'). In ScriptCraft, this function takes a single + parameter, an event object. All of the information about the event + is in the event object. + +In the example below, if a player joins the server and is an operator, +then the ScriptCraft plugin information will be displayed to that +player. + +```javascript +function onJoin( event ){ + if ( isOp(event.player) ) { + echo( event.player, 'Welcome to ' + __plugin ); + } +} +events.connection( onJoin ); +``` +First the onJoin() function is defined, this is our event handler - +the function we wish to be called every time some new player joins the +game. Then we hook up - or register - that function using the +events.connection() function. The events.connection function is the +function responsible for adding new *connection* event handlers - that +is - functions which should be invoked when there's a new *connection* +event in the game. A new *connection* event is fired whenever a player +joins the game. There are many other types of events you can handle in +Minecraft. You can see [a full list of events here][cmEvtList]. + +[cmEvtList]: #events-helper-module-canary-version +***/ + +// wph 20140927 - event handler registration differs depending on framework. +function onJoin( event ) { + if ( isOp(event.player) ) { + echo( event.player, 'Welcome to ' + __plugin ); + } +} +if (__plugin.canary){ + // canarymod + events.connection( onJoin ); +} else { + // bukkit + events.playerJoin( onJoin ); +} diff --git a/server/scriptcraft/plugins/homes/homes.js b/server/scriptcraft/plugins/homes/homes.js new file mode 100755 index 0000000..f6af3ec --- /dev/null +++ b/server/scriptcraft/plugins/homes/homes.js @@ -0,0 +1,404 @@ +/************************************************************************* +## homes Plugin + +The homes plugin lets players set a location as home and return to the +location, invite other players to their home and also visit other +player's homes. + +This module is a good example of how to create a javascript-based +minecraft mod which provides... + + * A programmatic interface (API) and + * A command extension which uses that API to provide new functionality for players. + +The module uses the `plugin()` function to specify an object and +methods, and the `command()` function to expose functionality to +players through a new `jsp home` command. This module also +demonstrates how to enable autocompletion for custom commands (to see +this in action, at the in-game prompt or server console prompt type +`jsp home ` then press the TAB key - you should see a list of further +possible options). + +The `jsp home` command has the following options... + +### Basic options + + * `/jsp home set` Will set your current location as your + 'home' location to which you can return at any time using the ... + + * `/jsp home` ..command will return you to your home, if you have set one. + + * `/jsp home {player}` Will take you to the home of {player} (where + {player} is the name of the player whose home you wish to visit. + + * `/jsp home delete` Deletes your home location from the location + database. This does not actually remove the home from the world or + change the world in any way. This command is completely + non-destructive and cannot be used for griefing. No blocks will be + destroyed by this command. + +### Social options +The following options allow players to open their homes to all or some +players, invite players to their home and see a list of homes they can +visit. + + * `/jsp home list` Lists home which you can visit. + * `/jsp home ilist` Lists players who can visit your home. + * `/jsp home invite {player}` Invites the named player to your home. + * `/jsp home uninvite {player}` Uninvites (revokes invitation) the named player to your home. + * `/jsp home public` Opens your home to all players (all players can visit your home). + * `/jsp home private` Makes your home private (no longer visitable by all). + +### Administration options +The following administration options can only be used by server operators... + + * `/jsp home listall` List all of the homes + * `/jsp home clear {player}` Removes the player's home + location. Again, this command does not destroy any structures in + the world, it simply removes the location from the database. No + blocks are destroyed by this command. + +***/ +var utils = require('utils'), + bkTeleportCause = org.bukkit.event.player.PlayerTeleportEvent.TeleportCause, + bkBukkit = org.bukkit.Bukkit, + _store = { + houses: { }, + openHouses: { }, + invites: { } + }; +/* +*/ +var homes = plugin( 'homes', { + + help: function( ) { + return [ + /* basic functions */ + '/jsp home : Return to your own home', + '/jsp home {player} : Go to player home', + '/jsp home set : Set your current location as home', + '/jsp home delete : Delete your home location', + + /* social */ + '/jsp home list : List homes you can visit', + '/jsp home ilist : List players who can visit your home', + '/jsp home invite {player} : Invite {player} to your home', + '/jsp home uninvite {player} : Uninvite {player} to your home', + '/jsp home public : Open your home to all players', + '/jsp home private : Make your home private', + + /* administration */ + '/jsp home listall : Show all houses (ops only)', + '/jsp home clear {player} : Clears player home location (ops only)' + ]; + }, + /* ======================================================================== + basic functions + ======================================================================== */ + + go: function( guest, host ) { + var loc, + homeLoc; + if ( typeof host == 'undefined' ) { + host = guest; + } + guest = utils.player( guest ); + host = utils.player( host ); + loc = _store.houses[ host.name ]; + if ( !loc ) { + echo( guest, host.name + ' has no home' ); + return; + } + if ( !this._canVisit( guest, host ) ) { + echo( guest, 'You can not visit ' + host.name + "'s home yet" ); + return; + } + homeLoc = utils.locationFromJSON( loc ); + guest.teleport(homeLoc, bkTeleportCause.PLUGIN); + }, + /* + determine whether a guest is allow visit a host's home + */ + _canVisit: function( guest, host ) { + var invitations, + i; + if ( guest == host ) { + return true; + } + if ( _store.openHouses[ host.name ] ) { + return true; + } + invitations = _store.invites[ host.name ]; + if ( invitations ) { + for ( i = 0; i < invitations.length; i++ ) { + if ( invitations[i] == guest.name ) { + return true; + } + } + } + return false; + }, + + set: function( player ) { + player = utils.player( player ); + var loc = player.location; + _store.houses[player.name] = utils.locationToJSON( loc ); + }, + + remove: function( player ) { + player = utils.player( player ); + delete _store.houses[ player.name ]; + }, + /* ======================================================================== + social functions + ======================================================================== */ + + /* + list homes which the player can visit + */ + list: function( player ) { + var result = [], + ohp, + host, + guests, + i; + for ( ohp in _store.openHouses ) { + result.push(ohp); + } + player = utils.player(player); + for ( host in _store.invites ) { + guests = _store.invites[host]; + for ( i = 0; i < guests.length; i++ ) { + if ( guests[i] == player.name ) { + result.push(host); + } + } + } + return result; + }, + /* + list who can visit the player home + */ + ilist: function( player ) { + var result = [], + onlinePlayers, + i; + player = utils.player( player ); + // if home is public - all players + if ( _store.openHouses[player.name] ) { + onlinePlayers = bkBukkit.getOnlinePlayers(); + for ( i = 0; i < onlinePlayers.length; i++ ) { + if ( onlinePlayers[i].name != player.name) { + result.push( onlinePlayers[i].name ); + } + } + } else { + if ( _store.invites[player.name] ) { + result = _store.invites[ player.name ]; + } else { + result = []; + } + } + return result; + }, + /* + Invite a player to the home + */ + invite: function( host, guest ) { + host = utils.player( host ); + guest = utils.player( guest ); + var invitations = []; + if ( _store.invites[host.name] ) { + invitations = _store.invites[host.name]; + } + invitations.push( guest.name ); + _store.invites[host.name] = invitations; + echo( guest, host.name + ' has invited you to their home.' ); + echo( guest, 'type "/jsp home ' + host.name + '" to accept' ); + }, + /* + Uninvite someone to the home + */ + uninvite: function( host, guest ) { + var invitations, + revisedInvites, + i; + host = utils.player( host ); + guest = utils.player( guest ); + invitations = _store.invites[ host.name ]; + if ( !invitations ) { + return; + } + revisedInvites = []; + for ( i = 0; i < invitations.length; i++ ) { + if ( invitations[i] != guest.name ) { + revisedInvites.push( invitations[i] ); + } + } + _store.invites[host.name] = revisedInvites; + }, + /* + make the player house public + */ + open: function( player, optionalMsg ) { + player = utils.player( player ); + _store.openHouses[ player.name ] = true; + if ( typeof optionalMsg != 'undefined' ) { + __plugin.server.broadcastMessage( optionalMsg ); + } + }, + + /* + make the player house private + */ + close: function( player ) { + player = utils.player( player ); + delete _store.openHouses[ player.name ]; + }, + /* ======================================================================== + admin functions + ======================================================================== */ + listall: function( ) { + var result = []; + for ( var home in _store.houses ) { + result.push(home); + } + return result; + }, + + clear: function( player ) { + player = utils.player( player ); + delete _store.houses[ player.name ]; + delete _store.openHouses[ player.name ]; + }, + store: _store +}, true ); + +exports.homes = homes; + +/* + define a set of command options that can be used by players + */ +var options = { + + 'set': function( params, sender ) { + homes.set( sender ); + }, + + 'delete': function( params, sender ) { + homes.remove( sender ); + }, + + 'help': function( params, sender ) { + echo( sender, homes.help() ); + }, + + 'list': function( params, sender ) { + var visitable = homes.list(); + if ( visitable.length == 0 ) { + echo( sender, 'There are no homes to visit' ); + return; + } else { + echo( sender, [ + 'You can visit any of these ' + visitable.length + ' homes' + ,visitable.join(', ') + ]); + } + }, + + 'ilist': function( params, sender ) { + var potentialVisitors = homes.ilist(); + if ( potentialVisitors.length == 0 ) { + echo( sender, 'No one can visit your home'); + } else { + echo( sender, [ + 'These ' + potentialVisitors.length + 'players can visit your home', + potentialVisitors.join(', ')]); + } + }, + + 'invite': function( params, sender ) { + if ( params.length == 1 ) { + echo( sender, 'You must provide a player name' ); + return; + } + var playerName = params[1]; + var guest = utils.player( playerName ); + if ( !guest ) { + echo( sender, playerName + ' is not here' ); + } else { + homes.invite( sender, guest ); + } + }, + + 'uninvite': function( params, sender ) { + if ( params.length == 1 ) { + echo( sender, 'You must provide a player name' ); + return; + } + var playerName = params[1]; + var guest = utils.player( playerName ); + if ( !guest ) { + echo( sender, playerName + ' is not here' ); + } else { + homes.uninvite( sender, guest ); + } + }, + + 'public': function( params, sender ) { + homes.open( sender, params.slice( 1 ).join(' ') ); + echo( sender, 'Your home is open to the public' ); + }, + + 'private': function( params, sender ) { + homes.close( sender ); + echo( sender, 'Your home is closed to the public' ); + }, + + 'listall': function( params, sender ) { + if ( !sender.isOp() ) { + echo( sender, 'Only operators can do this' ); + } else { + echo( sender, homes.listall().join(', ') ); + } + }, + + 'clear': function( params, sender ) { + if ( !sender.isOp() ) { + echo( sender, 'Only operators can do this' ); + } else { + homes.clear( params[1], sender ); + } + } +}; + +var optionList = []; +for ( var o in options ) { + optionList.push(o); +} + +/* + Expose a set of commands that players can use at the in-game command prompt + */ +command( 'home', function ( params , sender) { + var option, + host; + if ( params.length == 0 ) { + homes.go( sender, sender ); + return; + } + option = options[ params[0] ]; + if ( option ) { + option( params, sender ); + } else { + host = utils.player( params[0] ); + if ( !host ) { + echo( sender, params[0] + ' is not here' ); + } else { + homes.go( sender, host ); + } + } +}, optionList ); + + + diff --git a/server/scriptcraft/plugins/minigames/NumberGuess.js b/server/scriptcraft/plugins/minigames/NumberGuess.js new file mode 100755 index 0000000..56770b0 --- /dev/null +++ b/server/scriptcraft/plugins/minigames/NumberGuess.js @@ -0,0 +1,88 @@ +/************************************************************************* +## NumberGuess mini-game: + +### Description +This is a very simple number guessing game. Minecraft will ask you to +guess a number between 1 and 10 and you will tell you if you're too +hight or too low when you guess wrong. The purpose of this mini-game +code is to demonstrate use of Bukkit's Conversation API. + +### Example + + /js Game_NumberGuess.start(self) + +Once the game begins, guess a number by typing the `/` character +followed by a number between 1 and 10. + +***/ +var bkPrompt = org.bukkit.conversations.Prompt, + bkConversationFactory = org.bukkit.conversations.ConversationFactory, + bkConversationPrefix = org.bukkit.conversations.ConversationPrefix, + bkBukkit = org.bukkit.Bukkit; + +var sb = function( cmd ) { + bkBukkit.dispatchCommand( server.consoleSender, 'scoreboard ' + cmd ) ; +}; + +exports.Game_NumberGuess = { + start: function( sender ) { + + var guesses = 0; + + sb( 'objectives add NumberGuess dummy Guesses' ); + sb( 'players set ' + sender.name + ' NumberGuess ' + guesses ); + sb( 'objectives setdisplay sidebar NumberGuess' ); + + var number = Math.ceil( Math.random() * 10 ); + + var prompt = new bkPrompt( ) { + + getPromptText: function( ctx ) { + var hint = ''; + var h = ctx.getSessionData( 'hint' ); + if ( h ) { + hint = h; + } + return hint + 'Think of a number between 1 and 10'; + }, + + acceptInput: function( ctx, s ) { + s = s.replace( /^[^0-9]+/, '' ); // strip leading non-numeric characters (e.g. '/' ) + s = parseInt( s ); + if ( s == number ) { + setTimeout(function( ) { + ctx.forWhom.sendRawMessage( 'You guessed Correct!' ); + sb( 'objectives remove NumberGuess' ); + }, 100 ); + return null; + } else { + if ( s < number ) { + ctx.setSessionData( 'hint', 'too low\n' ); + } + if ( s > number ) { + ctx.setSessionData( 'hint', 'too high\n' ); + } + guesses++; + sb( 'players set ' + sender.name + ' NumberGuess ' + guesses ); + + return prompt; + } + }, + + blocksForInput: function( ctx ) { + return true; + } + }; + var convPrefix = new bkConversationPrefix( ) { + getPrefix: function( ctx ) { + return '[1-10] '; + } + }; + new bkConversationFactory( __plugin ) + .withModality( true ) + .withFirstPrompt( prompt ) + .withPrefix( convPrefix ) + .buildConversation( sender ) + .begin( ); + } +}; diff --git a/server/scriptcraft/plugins/minigames/cow-clicker.js b/server/scriptcraft/plugins/minigames/cow-clicker.js new file mode 100755 index 0000000..9b6836e --- /dev/null +++ b/server/scriptcraft/plugins/minigames/cow-clicker.js @@ -0,0 +1,204 @@ +/************************************************************************* +## Cow Clicker Mini-Game + +### How to Play + +At the in-game prompt type `jsp cowclicker` to start or stop +playing. Right-Click on Cows to score points. No points for killing +cows (hint: use the same keyboard keys you'd use for opening doors). + +Every time you click a cow your score increases by 1 point. Your score +is displayed in a side-bar along the right edge of of the screen. + +![cow clicker](img/cowclicker.png) + +### Rules + + * You can join and leave the Cow Clicker game at any time by typing + `/jsp cowclicker` at the in-game prompt. + + * Once you leave the game, your score is reset to zero. + + * When you disconnect from the server, your score will be reset to zero. + +### Gameplay Mechanics + +This is meant as a trivially simple use of the [Bukkit Scoreboard +API][bukscore]. There are many things you'll want to consider when constructing +your own mini-game... + + * Is the game itself a long-lived game - that is - should players and + scores be persisted (stored) between server restarts? + + * What should happen when a player quits the server - should this also be + understood as quitting the mini-game? + + * What should happen when a player who was previously playing the + mini-game, joins the server - should they automatically resume the + mini-game? + +[bukscore]: http://jd.bukkit.org/beta/apidocs/org/bukkit/scoreboard/package-summary.html + +***/ + +if (__plugin.canary || __plugin.bukkit){ + console.warn('cow-clicker minigame is not yet supported in CanaryMod and Craftbukkit'); + return; +} +var store = {}, + bkBukkit = org.bukkit.Bukkit, + bkCow = org.bukkit.entity.Cow, + bkOfflinePlayer = org.bukkit.OfflinePlayer, + scoreboardConfig = { + cowclicker: { + SIDEBAR: 'Cows Clicked' + } + }; +var scoreboard = require('minigames/scoreboard')(scoreboardConfig); + +var _onPlayerInteract = function( event ) { + var player = event.player, + clickedEntity = event.rightClicked, + loc = clickedEntity.location; + + if ( !store[ player.name ] ) { + return; + } + + var sound = function( snd, vol, pitch ) { + loc.world.playSound( loc, snd, vol, pitch ); + }; + + if ( clickedEntity instanceof bkCow) { + store[ player.name ].score++; + scoreboard.update( 'cowclicker', player, store[ player.name ].score ); + + bkBukkit.dispatchCommand( player, 'me clicked a cow!' ); + sound( bukkit.sound.CLICK, 1, 1 ); + setTimeout( function( ) { + sound( bukkit.sound.COW_HURT, 10, 0.85 ) ; + }, 200 ); + } +}; +var _onPlayerQuit = function( event ) { + _removePlayer( event.player ); +}; +var _onPlayerJoin = function( event ) { + var gamePlayer = store[event.player.name]; + if ( gamePlayer ) { + _addPlayer( event.player, gamePlayer.score ); + } +}; + +var _startGame = function( ) { + var p, + player; + if ( config.verbose ) { + console.log('Staring game: Cow Clicker'); + } + + events.playerQuit( _onPlayerQuit ); + events.playerJoin( _onPlayerJoin ); + events.playerInteractEntity( _onPlayerInteract ); + + scoreboard.start(); + + store = persist( 'cowclicker', store ); + for ( p in store ) { + player = server.getPlayer( p ); + if ( player ) { + /* + only add online players + */ + var score = store[p].score; + _addPlayer( player, score ); + } + } +}; + +var _addPlayer = function( player, score ) { + if ( config.verbose ) { + console.log( 'Adding player %s to Cow Clicker game', player ); + } + if ( typeof score == 'undefined' ) { + score = 0; + } + store[ player.name ] = { score: score }; + scoreboard.update( 'cowclicker', player, store[ player.name ].score); + + echo( player, 'Go forth and click some cows!' ); +}; + +var _removePlayer = function( player, notify ) { + + if ( player instanceof bkOfflinePlayer && player.player ) { + player = player.player; + } + + if ( !store[player.name] ) { + return; + } + if ( config.verbose ) { + console.log( 'Removing player %s from Cow Clicker', player ); + } + + var playerScore = store[ player.name ].score; + + scoreboard.restore( player ); + + delete store[ player.name ]; + if ( notify && player ) { + echo( player, 'You clicked ' + playerScore + ' cows! ' + + 'You must be tired after all that clicking.' ); + } +}; + +var _removeAllPlayers = function( notify ) { + if ( typeof notify == 'undefined' ) { + notify = false; + } + for ( var p in store ) { + var player = server.getOfflinePlayer( p ); + if ( player ) { + _removePlayer( player, notify ); + } + delete store[p]; + } +}; + +var _stopGame = function( removePlayers ) { + if ( typeof removePlayers == 'undefined' ) { + removePlayers = true; + } + if ( config.verbose ) { + console.log( 'Stopping game: Cow Clicker' ); + } + scoreboard.stop(); + if ( !removePlayers ) { + return; + } + _removeAllPlayers( false ); + persist( 'cowclicker', store.pers, 'w' ); + +}; +/* + start the game automatically when this module is loaded. + */ +_startGame(); +/* + players can join and leave the game by typing `jsp cowclicker` + */ +command( 'cowclicker', function( params, sender ) { + if ( !store[sender.name] ) { + _addPlayer( sender ); + } else { + _removePlayer( sender ); + } +}); +/* + stop the game when ScriptCraft is unloaded. + */ +addUnloadHandler( function( ) { + _stopGame( false ); +} ); + diff --git a/server/scriptcraft/plugins/signs/examples.js b/server/scriptcraft/plugins/signs/examples.js new file mode 100755 index 0000000..4bb39ba --- /dev/null +++ b/server/scriptcraft/plugins/signs/examples.js @@ -0,0 +1,51 @@ +var signs = require('signs'); +// +// Usage: +// +// In game, create a sign , target it and type ... +// +// /js signs.menu_food(); +// +// ... or ... +// +// /js signs.menu_time() +// + +var onDinnerChoice = function(event){ + echo( event.player, 'You chose ' + event.text); +}; +var convertToDinnerMenu = signs.menu('Dinner', + ['Lamb','Pork','Chicken','Duck','Beef'], + onDinnerChoice); + +var onTimeChoice = function(event){ + event.player.location.world.setTime( event.number * 6000 ); +}; +var convertToTimeMenu = signs.menu('Time', ['Dawn','Midday','Dusk','Midnight'], onTimeChoice); + +exports.signs = { + menu_food: function(cmdSender){ + var sign = signs.getTargetedBy(cmdSender); + if (!sign){ + throw new Error('You must look at an existing sign'); + } + convertToDinnerMenu(sign); + }, + // + // This is an example sign that displays a menu of times of day + // interacting with the sign will change the time of day accordingly. + // + // In game, create a sign , target it and type ... + // + // /js var signExamples = require('./signs/examples'); + // /js signExamples.timeOfDay() + // + menu_time: function(cmdSender){ + var sign = signs.getTargetedBy(cmdSender); + if (!sign){ + throw new Error('You must look at an existing sign'); + } + convertToTimeMenu(sign); + } +}; + diff --git a/server/scriptcraft/plugins/spawn.js b/server/scriptcraft/plugins/spawn.js new file mode 100755 index 0000000..dd6272f --- /dev/null +++ b/server/scriptcraft/plugins/spawn.js @@ -0,0 +1,61 @@ +'use strict'; +/*global Packages, __plugin, command, echo, isOp, org */ +/*jslint nomen: true, indent: 2 */ +/************************************************************************* +## Spawn Plugin + +Allows in-game operators to easily spawn creatures at current location. + +### Usage + + /jsp spawn cow + /jsp spawn sheep + /jsp spawn wolf + +This command supports TAB completion so to see a list of possible +entitities, type `/jsp spawn ' at the in-game command prompt, then +press TAB. Visit + (CanaryMod) +or (Bukkit) + +for a list of possible entities (creatures) which can be spawned. + +***/ +var entities = [], + entityType = null, + entitytypes, + t; +if (__plugin.bukkit) { + entityType = org.bukkit.entity.EntityType; +} +if (__plugin.canary) { + entityType = Packages.net.canarymod.api.entity.EntityType; +} +entitytypes = entityType.values(); +for (t in entitytypes) { + if (entitytypes[t] && entitytypes[t].ordinal) { + entities.push(entitytypes[t].name()); + } +} + +command('spawn', function (parameters, sender) { + if (!isOp(sender)) { + echo(sender, 'Only operators can perform this command'); + return; + } + var location = sender.location; + if (!location) { + echo(sender, 'You have no location. This command only works in-game.'); + return; + } + var world = location.world || sender.world, + type = ('' + parameters[0]).toUpperCase(); + if (__plugin.bukkit) { + world.spawnEntity(location, entityType[type]); + } + if (__plugin.canary) { + var Canary = Packages.net.canarymod.Canary, + entity = Canary.factory().entityFactory.newEntity(entityType[type], location); + entity.spawn(); + } +}, entities); diff --git a/server/scriptcraft/readme.md b/server/scriptcraft/readme.md new file mode 100755 index 0000000..ba82601 --- /dev/null +++ b/server/scriptcraft/readme.md @@ -0,0 +1,13 @@ +# scriptcraft root directory + +This directory contains the following subdirectories... + + * lib - contains core scriptcraft modules and code. + * modules - contains modules for use by others + * plugins - contains plugins (modules which are automatically loaded and globally-namespaced at startup) + +If you are a minecraft modder who wants to develop simple mods then the `plugins` location is where you should probably place your .js files. + +If you are a minecraft modder who wants to develop more complex mods or provide an API for other modders, then modules intended for use by plugins (your own or others) should probably be placed in the `modules` directory. + +The `lib` directory is reserved for use by ScriptCraft. If a module is considered essential for all, or adds significantly useful new functionality to ScriptCraft then it should be placed in the `lib` directory. diff --git a/server/usercache.json b/server/usercache.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/server/usercache.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/server/worlds/Roshar/Roshar_END/level.dat b/server/worlds/Roshar/Roshar_END/level.dat new file mode 100644 index 0000000..faa9d66 Binary files /dev/null and b/server/worlds/Roshar/Roshar_END/level.dat differ diff --git a/server/worlds/Roshar/Roshar_END/level.dat_old b/server/worlds/Roshar/Roshar_END/level.dat_old new file mode 100644 index 0000000..e7f2d9d Binary files /dev/null and b/server/worlds/Roshar/Roshar_END/level.dat_old differ diff --git a/server/worlds/Roshar/Roshar_END/region/r.-1.-1.mca b/server/worlds/Roshar/Roshar_END/region/r.-1.-1.mca new file mode 100644 index 0000000..455b9a9 Binary files /dev/null and b/server/worlds/Roshar/Roshar_END/region/r.-1.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_END/region/r.-1.0.mca b/server/worlds/Roshar/Roshar_END/region/r.-1.0.mca new file mode 100644 index 0000000..82b32a6 Binary files /dev/null and b/server/worlds/Roshar/Roshar_END/region/r.-1.0.mca differ diff --git a/server/worlds/Roshar/Roshar_END/region/r.0.-1.mca b/server/worlds/Roshar/Roshar_END/region/r.0.-1.mca new file mode 100644 index 0000000..f570d20 Binary files /dev/null and b/server/worlds/Roshar/Roshar_END/region/r.0.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_END/region/r.0.0.mca b/server/worlds/Roshar/Roshar_END/region/r.0.0.mca new file mode 100644 index 0000000..a1b1f8d Binary files /dev/null and b/server/worlds/Roshar/Roshar_END/region/r.0.0.mca differ diff --git a/server/worlds/Roshar/Roshar_END/region/r.1.-1.mca b/server/worlds/Roshar/Roshar_END/region/r.1.-1.mca new file mode 100644 index 0000000..78e3dda Binary files /dev/null and b/server/worlds/Roshar/Roshar_END/region/r.1.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_END/session.lock b/server/worlds/Roshar/Roshar_END/session.lock new file mode 100644 index 0000000..77d942f Binary files /dev/null and b/server/worlds/Roshar/Roshar_END/session.lock differ diff --git a/server/worlds/Roshar/Roshar_NETHER/level.dat b/server/worlds/Roshar/Roshar_NETHER/level.dat new file mode 100644 index 0000000..427a9b8 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/level.dat differ diff --git a/server/worlds/Roshar/Roshar_NETHER/level.dat_old b/server/worlds/Roshar/Roshar_NETHER/level.dat_old new file mode 100644 index 0000000..86a082c Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/level.dat_old differ diff --git a/server/worlds/Roshar/Roshar_NETHER/region/r.-1.-1.mca b/server/worlds/Roshar/Roshar_NETHER/region/r.-1.-1.mca new file mode 100644 index 0000000..ba8122c Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/region/r.-1.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_NETHER/region/r.-1.0.mca b/server/worlds/Roshar/Roshar_NETHER/region/r.-1.0.mca new file mode 100644 index 0000000..2a77a6f Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/region/r.-1.0.mca differ diff --git a/server/worlds/Roshar/Roshar_NETHER/region/r.-1.1.mca b/server/worlds/Roshar/Roshar_NETHER/region/r.-1.1.mca new file mode 100644 index 0000000..937dbe1 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/region/r.-1.1.mca differ diff --git a/server/worlds/Roshar/Roshar_NETHER/region/r.0.-1.mca b/server/worlds/Roshar/Roshar_NETHER/region/r.0.-1.mca new file mode 100644 index 0000000..28e71e8 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/region/r.0.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_NETHER/region/r.0.0.mca b/server/worlds/Roshar/Roshar_NETHER/region/r.0.0.mca new file mode 100644 index 0000000..6daed48 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/region/r.0.0.mca differ diff --git a/server/worlds/Roshar/Roshar_NETHER/region/r.0.1.mca b/server/worlds/Roshar/Roshar_NETHER/region/r.0.1.mca new file mode 100644 index 0000000..9fde57f Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/region/r.0.1.mca differ diff --git a/server/worlds/Roshar/Roshar_NETHER/region/r.1.-1.mca b/server/worlds/Roshar/Roshar_NETHER/region/r.1.-1.mca new file mode 100644 index 0000000..e1857a0 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/region/r.1.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_NETHER/session.lock b/server/worlds/Roshar/Roshar_NETHER/session.lock new file mode 100644 index 0000000..671c403 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NETHER/session.lock differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/data/Fortress.dat b/server/worlds/Roshar/Roshar_NORMAL/data/Fortress.dat new file mode 100644 index 0000000..44a4664 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/data/Fortress.dat differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/data/idcounts.dat b/server/worlds/Roshar/Roshar_NORMAL/data/idcounts.dat new file mode 100644 index 0000000..4df64be Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/data/idcounts.dat differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/data/map_0.dat b/server/worlds/Roshar/Roshar_NORMAL/data/map_0.dat new file mode 100644 index 0000000..4ef03de Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/data/map_0.dat differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/data/villages.dat b/server/worlds/Roshar/Roshar_NORMAL/data/villages.dat new file mode 100755 index 0000000..6c0e5f1 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/data/villages.dat differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/data/villages_end.dat b/server/worlds/Roshar/Roshar_NORMAL/data/villages_end.dat new file mode 100755 index 0000000..8b274cb Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/data/villages_end.dat differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/data/villages_nether.dat b/server/worlds/Roshar/Roshar_NORMAL/data/villages_nether.dat new file mode 100755 index 0000000..97ea9a6 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/data/villages_nether.dat differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/level.dat b/server/worlds/Roshar/Roshar_NORMAL/level.dat new file mode 100644 index 0000000..b3724bd Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/level.dat differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/level.dat_mcr b/server/worlds/Roshar/Roshar_NORMAL/level.dat_mcr new file mode 100755 index 0000000..2a1cf69 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/level.dat_mcr differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/level.dat_old b/server/worlds/Roshar/Roshar_NORMAL/level.dat_old new file mode 100644 index 0000000..503795d Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/level.dat_old differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/playerdata/7adfda8e-7c82-4ee1-88e2-6d407ff93a21.dat b/server/worlds/Roshar/Roshar_NORMAL/playerdata/7adfda8e-7c82-4ee1-88e2-6d407ff93a21.dat new file mode 100755 index 0000000..3c55b4a Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/playerdata/7adfda8e-7c82-4ee1-88e2-6d407ff93a21.dat differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.-1.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.-1.mca new file mode 100755 index 0000000..0cceca6 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.-2.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.-2.mca new file mode 100644 index 0000000..c7323e1 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.-2.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.0.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.0.mca new file mode 100755 index 0000000..8f12241 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.-1.0.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.0.-1.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.0.-1.mca new file mode 100755 index 0000000..9540453 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.0.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.0.-2.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.0.-2.mca new file mode 100755 index 0000000..23f3949 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.0.-2.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.0.0.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.0.0.mca new file mode 100755 index 0000000..510edb3 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.0.0.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.1.-1.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.1.-1.mca new file mode 100755 index 0000000..7a55224 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.1.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.1.-2.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.1.-2.mca new file mode 100755 index 0000000..2abb85f Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.1.-2.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.1.0.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.1.0.mca new file mode 100755 index 0000000..efae400 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.1.0.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.2.-1.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.2.-1.mca new file mode 100755 index 0000000..f7300be Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.2.-1.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.2.-2.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.2.-2.mca new file mode 100644 index 0000000..2541849 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.2.-2.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/region/r.2.0.mca b/server/worlds/Roshar/Roshar_NORMAL/region/r.2.0.mca new file mode 100755 index 0000000..65a36e3 Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/region/r.2.0.mca differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/session.lock b/server/worlds/Roshar/Roshar_NORMAL/session.lock new file mode 100755 index 0000000..99e5fec Binary files /dev/null and b/server/worlds/Roshar/Roshar_NORMAL/session.lock differ diff --git a/server/worlds/Roshar/Roshar_NORMAL/stats/7adfda8e-7c82-4ee1-88e2-6d407ff93a21.json b/server/worlds/Roshar/Roshar_NORMAL/stats/7adfda8e-7c82-4ee1-88e2-6d407ff93a21.json new file mode 100755 index 0000000..68cb3e4 --- /dev/null +++ b/server/worlds/Roshar/Roshar_NORMAL/stats/7adfda8e-7c82-4ee1-88e2-6d407ff93a21.json @@ -0,0 +1 @@ +{"stat.useItem.minecraft.cobblestone":6,"achievement.openInventory":2,"achievement.exploreAllBiomes":{"value":0,"progress":["Plains"]},"stat.flyOneCm":42288,"stat.timeSinceDeath":2083,"stat.playOneMinute":2083,"stat.leaveGame":2,"stat.jump":15,"stat.walkOneCm":6348,"stat.useItem.minecraft.dirt":4} \ No newline at end of file diff --git a/server/worlds/players/08d6ef60-f157-3a8e-a04f-6af73400697c.dat b/server/worlds/players/08d6ef60-f157-3a8e-a04f-6af73400697c.dat new file mode 100644 index 0000000..e749181 Binary files /dev/null and b/server/worlds/players/08d6ef60-f157-3a8e-a04f-6af73400697c.dat differ diff --git a/server/worlds/players/14801086-f435-35d3-973a-6fe8572874c9.dat b/server/worlds/players/14801086-f435-35d3-973a-6fe8572874c9.dat new file mode 100644 index 0000000..60906d0 Binary files /dev/null and b/server/worlds/players/14801086-f435-35d3-973a-6fe8572874c9.dat differ diff --git a/server/worlds/players/2494bee9-581d-3809-90d8-0d199b81c0a9.dat b/server/worlds/players/2494bee9-581d-3809-90d8-0d199b81c0a9.dat new file mode 100644 index 0000000..fd357a0 Binary files /dev/null and b/server/worlds/players/2494bee9-581d-3809-90d8-0d199b81c0a9.dat differ diff --git a/server/worlds/players/28755a9a-d3ba-366a-8837-bbd63051e079.dat b/server/worlds/players/28755a9a-d3ba-366a-8837-bbd63051e079.dat new file mode 100644 index 0000000..90f269c Binary files /dev/null and b/server/worlds/players/28755a9a-d3ba-366a-8837-bbd63051e079.dat differ diff --git a/server/worlds/players/b8e2bb98-f74f-3373-a144-0107bca542b7.dat b/server/worlds/players/b8e2bb98-f74f-3373-a144-0107bca542b7.dat new file mode 100644 index 0000000..aa2ab88 Binary files /dev/null and b/server/worlds/players/b8e2bb98-f74f-3373-a144-0107bca542b7.dat differ diff --git a/server/worlds/players/b9075e8f-4773-3d2e-a08c-64345403cc03.dat b/server/worlds/players/b9075e8f-4773-3d2e-a08c-64345403cc03.dat new file mode 100644 index 0000000..7d07151 Binary files /dev/null and b/server/worlds/players/b9075e8f-4773-3d2e-a08c-64345403cc03.dat differ diff --git a/server/worlds/scoreboards/session.lock b/server/worlds/scoreboards/session.lock new file mode 100644 index 0000000..5bc4f17 Binary files /dev/null and b/server/worlds/scoreboards/session.lock differ diff --git a/server/worlds/stats/08d6ef60-f157-3a8e-a04f-6af73400697c.json b/server/worlds/stats/08d6ef60-f157-3a8e-a04f-6af73400697c.json new file mode 100644 index 0000000..943d4b4 --- /dev/null +++ b/server/worlds/stats/08d6ef60-f157-3a8e-a04f-6af73400697c.json @@ -0,0 +1 @@ +{"stat.useItem.minecraft.anvil":10,"stat.useItem.minecraft.glass_pane":54,"stat.crouchOneCm":7731,"achievement.exploreAllBiomes":{"value":0,"progress":["Plains","The End","Hell"]},"stat.useItem.minecraft.tnt":1,"stat.useItem.minecraft.redstone_block":1,"stat.useItem.minecraft.quartz_block":166,"stat.useItem.minecraft.command_block":1,"stat.useItem.minecraft.carrot_on_a_stick":40,"stat.useItem.minecraft.wooden_door":3,"stat.useItem.minecraft.minecart":2,"achievement.openInventory":97,"stat.useItem.minecraft.fire_charge":151,"stat.damageDealt":1025,"stat.useItem.minecraft.item_frame":12,"stat.useItem.minecraft.planks":7,"stat.useItem.minecraft.quartz_stairs":71,"stat.useItem.minecraft.stained_hardened_clay":6,"stat.flyOneCm":1246113,"stat.useItem.minecraft.skull":22,"stat.useItem.minecraft.stonebrick":4,"stat.useItem.minecraft.writable_book":2,"stat.useItem.minecraft.golden_rail":24,"stat.useItem.minecraft.stone":5,"stat.useItem.minecraft.red_flower":6,"stat.damageTaken":1000,"stat.useItem.minecraft.torch":24,"stat.useItem.minecraft.rail":111,"stat.useItem.minecraft.diamond_sword":10,"stat.pigOneCm":345288,"stat.climbOneCm":424,"stat.useItem.minecraft.redstone":16,"stat.useItem.minecraft.potion":67,"stat.useItem.minecraft.yellow_flower":4,"stat.drop":26,"stat.useItem.minecraft.dropper":1,"stat.useItem.minecraft.stone_pressure_plate":1,"stat.leaveGame":8,"stat.useItem.minecraft.comparator":1,"stat.useItem.minecraft.lever":3,"stat.useItem.minecraft.activator_rail":2,"stat.useItem.minecraft.soul_sand":50,"stat.killEntity.Slime":7,"stat.useItem.minecraft.snow":2,"stat.useItem.minecraft.stone_slab":20,"stat.timeSinceDeath":18233,"stat.playOneMinute":450197,"stat.useItem.minecraft.wool":380,"stat.killEntity.Rabbit":1,"stat.useItem.minecraft.pumpkin":1,"stat.useItem.minecraft.written_book":1,"stat.deaths":11,"stat.mobKills":8,"stat.horseOneCm":54853,"stat.walkOneCm":665764,"stat.useItem.minecraft.sandstone":10,"stat.useItem.minecraft.sign":1,"stat.minecartOneCm":18986,"stat.jump":325,"stat.useItem.minecraft.piston":12,"stat.useItem.minecraft.detector_rail":1,"stat.useItem.minecraft.spawn_egg":51,"stat.sprintOneCm":52559,"stat.useItem.minecraft.dirt":33} \ No newline at end of file diff --git a/server/worlds/stats/14801086-f435-35d3-973a-6fe8572874c9.json b/server/worlds/stats/14801086-f435-35d3-973a-6fe8572874c9.json new file mode 100644 index 0000000..911c1c3 --- /dev/null +++ b/server/worlds/stats/14801086-f435-35d3-973a-6fe8572874c9.json @@ -0,0 +1 @@ +{"stat.useItem.minecraft.anvil":2,"stat.crouchOneCm":6,"stat.useItem.minecraft.wooden_door":1,"stat.useItem.minecraft.minecart":1,"achievement.openInventory":84,"stat.killEntity.Sheep":2,"stat.damageDealt":1155,"stat.useItem.minecraft.fence":4,"achievement.exploreAllBiomes":{"value":0,"progress":["Plains","The End","Hell"]},"stat.useItem.minecraft.log":16,"stat.useItem.minecraft.iron_block":11,"stat.useItem.minecraft.bed":1,"stat.useItem.minecraft.stained_hardened_clay":16,"stat.fallOneCm":1455,"stat.flyOneCm":617470,"stat.useItem.minecraft.diamond_sword":7,"stat.useItem.minecraft.enchanting_table":1,"stat.useItem.minecraft.golden_rail":4,"stat.useItem.minecraft.stone":132,"stat.killEntity.EntityHorse":2,"stat.drop":13,"stat.damageTaken":2690,"stat.useItem.minecraft.torch":13,"stat.timeSinceDeath":5440,"stat.leaveGame":6,"stat.useItem.minecraft.bow":4,"stat.useItem.minecraft.crafting_table":2,"stat.useItem.minecraft.lead":1,"stat.playOneMinute":443881,"stat.useItem.minecraft.wool":3,"stat.killEntity.Slime":6,"stat.useItem.minecraft.pumpkin":1,"stat.entityKilledBy.Slime":3,"stat.deaths":19,"stat.jump":287,"stat.mobKills":10,"stat.horseOneCm":203957,"stat.useItem.minecraft.spawn_egg":35,"stat.walkOneCm":486037,"stat.useItem.minecraft.slime":9,"stat.minecartOneCm":31866,"stat.sprintOneCm":29135,"stat.useItem.minecraft.dirt":12} \ No newline at end of file diff --git a/server/worlds/stats/2494bee9-581d-3809-90d8-0d199b81c0a9.json b/server/worlds/stats/2494bee9-581d-3809-90d8-0d199b81c0a9.json new file mode 100644 index 0000000..f01da82 --- /dev/null +++ b/server/worlds/stats/2494bee9-581d-3809-90d8-0d199b81c0a9.json @@ -0,0 +1 @@ +{"stat.useItem.minecraft.anvil":2,"stat.crouchOneCm":4725,"stat.useItem.minecraft.chest":1,"stat.killEntity.Sheep":1,"stat.useItem.minecraft.cobblestone":52,"stat.useItem.minecraft.stone_button":3,"achievement.exploreAllBiomes":{"value":0,"progress":["Plains","The End"]},"stat.useItem.minecraft.leaves":1,"stat.useItem.minecraft.tnt":11,"achievement.openInventory":75,"stat.damageDealt":18988,"stat.useItem.minecraft.obsidian":22,"stat.craftItem.minecraft.leather_helmet":1,"stat.flyOneCm":1149547,"stat.useItem.minecraft.skull":9,"stat.useItem.minecraft.stone":6,"stat.craftItem.minecraft.leather_boots":1,"stat.damageTaken":3000,"stat.useItem.minecraft.torch":30,"stat.useItem.minecraft.end_portal_frame":30,"stat.useItem.minecraft.dispenser":3,"stat.useItem.minecraft.diamond_sword":135,"stat.killEntity.EntityHorse":1,"stat.useItem.minecraft.flint_and_steel":3,"stat.pigOneCm":263,"stat.useItem.minecraft.redstone":20,"stat.useItem.minecraft.sapling":11,"stat.drop":30,"stat.useItem.minecraft.dropper":2,"stat.leaveGame":5,"stat.useItem.minecraft.glowstone":9,"stat.useItem.minecraft.bow":2,"stat.useItem.minecraft.lever":2,"stat.useItem.minecraft.soul_sand":13,"stat.killEntity.Spider":1,"stat.killEntity.Slime":16,"stat.useItem.minecraft.stone_slab":22,"stat.timeSinceDeath":9504,"stat.craftItem.minecraft.leather_chestplate":1,"stat.killEntity.Creeper":1,"stat.useItem.minecraft.ender_eye":28,"stat.useItem.minecraft.crafting_table":2,"stat.playOneMinute":428935,"stat.killEntity.Rabbit":2,"stat.killEntity.Pig":1,"stat.deaths":21,"stat.craftItem.minecraft.leather_leggings":1,"stat.mobKills":26,"stat.killEntity.Skeleton":1,"stat.horseOneCm":50256,"stat.walkOneCm":796839,"stat.useItem.minecraft.stone_stairs":10,"stat.useItem.minecraft.sign":1,"stat.useItem.minecraft.sandstone":8,"stat.jump":357,"stat.useItem.minecraft.spawn_egg":1,"stat.sprintOneCm":10777,"stat.useItem.minecraft.dirt":24} \ No newline at end of file diff --git a/server/worlds/stats/28755a9a-d3ba-366a-8837-bbd63051e079.json b/server/worlds/stats/28755a9a-d3ba-366a-8837-bbd63051e079.json new file mode 100644 index 0000000..d6b3283 --- /dev/null +++ b/server/worlds/stats/28755a9a-d3ba-366a-8837-bbd63051e079.json @@ -0,0 +1 @@ +{"stat.useItem.minecraft.glass_pane":42,"stat.crouchOneCm":532,"stat.useItem.minecraft.diamond_pickaxe":9,"stat.killEntity.Sheep":1,"stat.useItem.minecraft.stone_button":1,"achievement.exploreAllBiomes":{"value":0,"progress":["Plains","The End","Hell"]},"stat.useItem.minecraft.tnt":6,"stat.useItem.minecraft.heavy_weighted_pressure_plate":4,"stat.useItem.minecraft.spruce_door":1,"stat.useItem.minecraft.command_block":3,"stat.useItem.minecraft.carrot_on_a_stick":42,"stat.useItem.minecraft.wooden_door":3,"achievement.openInventory":97,"stat.damageDealt":11590,"stat.useItem.minecraft.experience_bottle":39,"stat.useItem.minecraft.obsidian":15,"stat.killEntity.Cow":1,"stat.fallOneCm":991,"stat.useItem.minecraft.stained_hardened_clay":5,"stat.flyOneCm":1163766,"stat.useItem.minecraft.skull":6,"stat.useItem.minecraft.stonebrick":17,"stat.useItem.minecraft.stone":5,"stat.damageTaken":2120,"stat.useItem.minecraft.monster_egg":1,"stat.useItem.minecraft.dispenser":7,"stat.useItem.minecraft.diamond_sword":121,"stat.useItem.minecraft.redstone_lamp":13,"stat.killEntity.EntityHorse":2,"stat.useItem.minecraft.sponge":78,"stat.useItem.minecraft.flint_and_steel":9,"stat.pigOneCm":36267,"stat.useItem.minecraft.potion":2,"stat.useItem.minecraft.redstone":3,"stat.drop":2,"stat.killEntity.Enderman":2,"stat.leaveGame":7,"stat.useItem.minecraft.bow":37,"stat.useItem.minecraft.lever":3,"stat.useItem.minecraft.glass":15,"stat.useItem.minecraft.soul_sand":9,"stat.useItem.minecraft.sand":3,"stat.killEntity.Slime":37,"stat.timeSinceDeath":38328,"stat.useItem.minecraft.egg":136,"stat.playOneMinute":451081,"stat.killEntity.Rabbit":3,"stat.killEntity.Pig":3,"stat.deaths":17,"stat.mobKills":51,"stat.horseOneCm":141609,"stat.walkOneCm":796519,"stat.useItem.minecraft.stone_stairs":22,"stat.useItem.minecraft.sandstone":2,"stat.useItem.minecraft.sign":1,"stat.useItem.minecraft.saddle":6,"stat.jump":283,"stat.useItem.minecraft.beacon":9,"stat.killEntity.Witch":1,"stat.useItem.minecraft.spawn_egg":21,"stat.sprintOneCm":3231,"stat.useItem.minecraft.dirt":7} \ No newline at end of file diff --git a/server/worlds/stats/b8e2bb98-f74f-3373-a144-0107bca542b7.json b/server/worlds/stats/b8e2bb98-f74f-3373-a144-0107bca542b7.json new file mode 100644 index 0000000..67cd85a --- /dev/null +++ b/server/worlds/stats/b8e2bb98-f74f-3373-a144-0107bca542b7.json @@ -0,0 +1 @@ +{"stat.useItem.minecraft.anvil":3,"stat.useItem.minecraft.glass_pane":7,"stat.crouchOneCm":1985,"stat.useItem.minecraft.cobblestone":11,"stat.useItem.minecraft.sticky_piston":3,"achievement.exploreAllBiomes":{"value":0,"progress":["Plains","The End","Hell"]},"stat.useItem.minecraft.tnt":11,"stat.useItem.minecraft.command_block":1,"stat.useItem.minecraft.carrot_on_a_stick":1,"stat.useItem.minecraft.minecart":2,"achievement.openInventory":102,"stat.damageDealt":1480,"stat.useItem.minecraft.obsidian":12,"stat.useItem.minecraft.item_frame":3,"stat.useItem.minecraft.brick_block":3,"stat.useItem.minecraft.planks":85,"stat.talkedToVillager":1,"stat.useItem.minecraft.stained_hardened_clay":3,"stat.fallOneCm":756,"stat.flyOneCm":756461,"stat.useItem.minecraft.stonebrick":3,"stat.useItem.minecraft.golden_rail":13,"stat.useItem.minecraft.stone":37,"stat.useItem.minecraft.red_flower":1,"stat.useItem.minecraft.prismarine":1,"stat.useItem.minecraft.birch_door":2,"stat.damageTaken":1195,"stat.useItem.minecraft.torch":18,"stat.useItem.minecraft.bed":7,"stat.useItem.minecraft.diamond_sword":13,"stat.useItem.minecraft.ladder":3,"stat.mineBlock.minecraft.prismarine":1,"stat.useItem.minecraft.flint_and_steel":1,"stat.pigOneCm":50858,"stat.climbOneCm":848,"stat.useItem.minecraft.cake":12,"stat.useItem.minecraft.oak_stairs":13,"stat.drop":39,"stat.useItem.minecraft.golden_pickaxe":1,"stat.timeSinceDeath":98142,"stat.leaveGame":2,"stat.useItem.minecraft.egg":12,"stat.killEntity.Creeper":1,"stat.diveOneCm":447,"stat.useItem.minecraft.bow":2,"stat.useItem.minecraft.lever":4,"stat.playOneMinute":446952,"stat.useItem.minecraft.redstone_torch":8,"stat.useItem.minecraft.wool":10,"stat.killEntity.Slime":4,"stat.useItem.minecraft.stone_slab":54,"stat.deaths":10,"stat.useItem.minecraft.wooden_slab":3,"stat.swimOneCm":2235,"stat.mobKills":7,"stat.killEntity.Skeleton":1,"stat.horseOneCm":20697,"stat.walkOneCm":696092,"stat.useItem.minecraft.sign":4,"stat.minecartOneCm":8479,"stat.useItem.minecraft.carpet":6,"stat.jump":313,"stat.useItem.minecraft.armor_stand":3,"stat.useItem.minecraft.beacon":2,"stat.useItem.minecraft.spawn_egg":99,"stat.killEntity.Guardian":1,"stat.sprintOneCm":44406,"stat.useItem.minecraft.dirt":16} \ No newline at end of file diff --git a/server/worlds/stats/b9075e8f-4773-3d2e-a08c-64345403cc03.json b/server/worlds/stats/b9075e8f-4773-3d2e-a08c-64345403cc03.json new file mode 100644 index 0000000..81139ee --- /dev/null +++ b/server/worlds/stats/b9075e8f-4773-3d2e-a08c-64345403cc03.json @@ -0,0 +1 @@ +{"stat.useItem.minecraft.glass_pane":3,"stat.crouchOneCm":243,"stat.useItem.minecraft.command_block":1,"stat.useItem.minecraft.wooden_door":11,"achievement.openInventory":108,"stat.killEntity.Sheep":3,"stat.damageDealt":2105,"stat.useItem.minecraft.cobblestone":12,"achievement.exploreAllBiomes":{"value":0,"progress":["Plains","The End","Hell"]},"stat.talkedToVillager":1,"stat.useItem.minecraft.stained_hardened_clay":143,"stat.fallOneCm":756,"stat.useItem.minecraft.stonebrick":4,"stat.flyOneCm":1053226,"stat.useItem.minecraft.stone":76,"stat.useItem.minecraft.prismarine":23,"stat.damageTaken":1630,"stat.useItem.minecraft.torch":14,"stat.useItem.minecraft.end_portal_frame":18,"stat.useItem.minecraft.rail":1,"stat.useItem.minecraft.diamond_sword":21,"stat.useItem.minecraft.enchanting_table":2,"stat.useItem.minecraft.flint_and_steel":7,"stat.drop":36,"stat.timeSinceDeath":26669,"stat.leaveGame":4,"stat.killEntity.Creeper":2,"stat.useItem.minecraft.bow":4,"stat.useItem.minecraft.ender_eye":14,"stat.playOneMinute":433510,"stat.killEntity.Slime":8,"stat.useItem.minecraft.birch_fence":1,"stat.entityKilledBy.Slime":1,"stat.deaths":13,"stat.useItem.minecraft.fishing_rod":10,"stat.useItem.minecraft.dark_oak_door":11,"stat.mobKills":13,"stat.horseOneCm":108217,"stat.walkOneCm":301048,"stat.useItem.minecraft.sign":2,"stat.useItem.minecraft.saddle":1,"stat.jump":234,"stat.useItem.minecraft.armor_stand":2,"stat.useItem.minecraft.banner":4,"stat.useItem.minecraft.spawn_egg":13,"stat.useItem.minecraft.sea_lantern":1,"stat.sprintOneCm":110,"stat.useItem.minecraft.dirt":165} \ No newline at end of file