summaryrefslogtreecommitdiffstats
path: root/MCServer
diff options
context:
space:
mode:
authorfaketruth <faketruth@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-08-20 14:20:20 +0200
committerfaketruth <faketruth@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-08-20 14:20:20 +0200
commit12906c026d414c752d3c0ba9481f425b24b29c67 (patch)
treed64298334a68275e0d7c22c9dfb0e82c95654f83 /MCServer
parentWindow, Chest, Furnace and Pawn are not using cPackets at all (diff)
downloadcuberite-12906c026d414c752d3c0ba9481f425b24b29c67.tar
cuberite-12906c026d414c752d3c0ba9481f425b24b29c67.tar.gz
cuberite-12906c026d414c752d3c0ba9481f425b24b29c67.tar.bz2
cuberite-12906c026d414c752d3c0ba9481f425b24b29c67.tar.lz
cuberite-12906c026d414c752d3c0ba9481f425b24b29c67.tar.xz
cuberite-12906c026d414c752d3c0ba9481f425b24b29c67.tar.zst
cuberite-12906c026d414c752d3c0ba9481f425b24b29c67.zip
Diffstat (limited to 'MCServer')
-rw-r--r--MCServer/Plugins/ChatLog/plugin.lua17
-rw-r--r--MCServer/Plugins/Core/ban.lua30
-rw-r--r--MCServer/Plugins/Core/coords.lua4
-rw-r--r--MCServer/Plugins/Core/gamemode.lua10
-rw-r--r--MCServer/Plugins/Core/gotoworld.lua15
-rw-r--r--MCServer/Plugins/Core/help.lua54
-rw-r--r--MCServer/Plugins/Core/item.lua65
-rw-r--r--MCServer/Plugins/Core/kick.lua27
-rw-r--r--MCServer/Plugins/Core/main.lua147
-rw-r--r--MCServer/Plugins/Core/motd.lua10
-rw-r--r--MCServer/Plugins/Core/onblockdig.lua10
-rw-r--r--MCServer/Plugins/Core/onblockplace.lua63
-rw-r--r--MCServer/Plugins/Core/oncraftingnorecipe.lua214
-rw-r--r--MCServer/Plugins/Core/onkilled.lua24
-rw-r--r--MCServer/Plugins/Core/onlogin.lua20
-rw-r--r--MCServer/Plugins/Core/onplayerjoin.lua4
-rw-r--r--MCServer/Plugins/Core/playerlist.lua14
-rw-r--r--MCServer/Plugins/Core/pluginlist.lua13
-rw-r--r--MCServer/Plugins/Core/regeneratechunk.lua18
-rw-r--r--MCServer/Plugins/Core/reload.lua6
-rw-r--r--MCServer/Plugins/Core/spawn.lua6
-rw-r--r--MCServer/Plugins/Core/stop.lua6
-rw-r--r--MCServer/Plugins/Core/teleport.lua23
-rw-r--r--MCServer/Plugins/Core/time.lua18
-rw-r--r--MCServer/Plugins/Core/top.lua11
-rw-r--r--MCServer/Plugins/Core/unban.lua20
-rw-r--r--MCServer/Plugins/Core/viewdistance.lua10
-rw-r--r--MCServer/Plugins/Core/web_manageplugins.lua93
-rw-r--r--MCServer/Plugins/Core/web_permissions.lua79
-rw-r--r--MCServer/Plugins/Core/web_playerlist.lua36
-rw-r--r--MCServer/Plugins/Core/web_whitelist.lua79
-rw-r--r--MCServer/Plugins/MagicCarpet/objects.lua97
-rw-r--r--MCServer/Plugins/MagicCarpet/plugin.lua65
-rw-r--r--MCServer/Plugins/SquirrelChatLog.nut13
-rw-r--r--MCServer/Plugins/sTick/main.lua20
-rw-r--r--MCServer/Plugins/sTick/onblockplace.lua18
-rw-r--r--MCServer/banned.example.ini3
-rw-r--r--MCServer/crafting.txt357
-rw-r--r--MCServer/furnace.txt64
-rw-r--r--MCServer/groups.example.ini17
-rw-r--r--MCServer/groups.ini17
-rw-r--r--MCServer/items.ini471
-rw-r--r--MCServer/monsters.ini111
-rw-r--r--MCServer/settings.example.ini31
-rw-r--r--MCServer/settings.ini37
-rw-r--r--MCServer/terrain.ini8
-rw-r--r--MCServer/users.example.ini8
-rw-r--r--MCServer/users.ini20
-rw-r--r--MCServer/webadmin.example.ini6
-rw-r--r--MCServer/webadmin.ini6
-rw-r--r--MCServer/webadmin/template.html376
-rw-r--r--MCServer/whitelist.example.ini6
52 files changed, 2897 insertions, 0 deletions
diff --git a/MCServer/Plugins/ChatLog/plugin.lua b/MCServer/Plugins/ChatLog/plugin.lua
new file mode 100644
index 000000000..e18a8e642
--- /dev/null
+++ b/MCServer/Plugins/ChatLog/plugin.lua
@@ -0,0 +1,17 @@
+function Initialize( Plugin )
+ Plugin:SetName( "ChatLog" )
+ Plugin:SetVersion( 2 )
+
+ PluginManager = cRoot:Get():GetPluginManager()
+ PluginManager:AddHook( Plugin, cPluginManager.E_PLUGIN_CHAT )
+
+ LOG( "Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion() )
+ return true
+end
+
+function OnChat( Message, Player )
+ -- Lets get loggin'
+ LOGINFO("[" .. Player:GetName() .. "]: " .. Message);
+
+ return false
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/ban.lua b/MCServer/Plugins/Core/ban.lua
new file mode 100644
index 000000000..a6a662c3c
--- /dev/null
+++ b/MCServer/Plugins/Core/ban.lua
@@ -0,0 +1,30 @@
+function HandleBanCommand( Split, Player )
+ if( #Split < 2 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /ban [Player] <Reason>" )
+ return true
+ end
+
+ local World = Player:GetWorld()
+ local OtherPlayer = World:GetPlayer( Split[2] )
+ if( OtherPlayer == nil ) then
+ Player:SendMessage( cChatColor.Green .. "Could not find player " .. Split[2] )
+ return true
+ end
+
+ local Reason = "You have been banned"
+ if( #Split > 2 ) then
+ Reason = table.concat(Split, " ", 3)
+ end
+
+ local Server = cRoot:Get():GetServer()
+ LOGINFO( Player:GetName() .. " is banning " .. OtherPlayer:GetName() .. " ( "..Reason..") " )
+ Server:SendMessage( "Banning " .. OtherPlayer:GetName() )
+
+ local ClientHandle = OtherPlayer:GetClientHandle()
+ ClientHandle:Kick( Reason )
+
+ BannedPlayersIni:SetValueB("Banned", OtherPlayer:GetName(), true)
+ BannedPlayersIni:WriteFile()
+
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/coords.lua b/MCServer/Plugins/Core/coords.lua
new file mode 100644
index 000000000..07cda1a92
--- /dev/null
+++ b/MCServer/Plugins/Core/coords.lua
@@ -0,0 +1,4 @@
+function HandleCoordsCommand( Split, Player )
+ Player:SendMessage(cChatColor.Green .. string.format("[X:%0.2f] [Y:%0.2f] [Z:%0.2f]", Player:GetPosX(), Player:GetPosY(), Player:GetPosZ() ) )
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/gamemode.lua b/MCServer/Plugins/Core/gamemode.lua
new file mode 100644
index 000000000..1e73b46fd
--- /dev/null
+++ b/MCServer/Plugins/Core/gamemode.lua
@@ -0,0 +1,10 @@
+function HandleChangeGMCommand( Split, Player )
+ if( #Split ~= 2 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /gm [GameMode (0|1)]" )
+ return true
+ end
+
+ Player:SetGameMode(Split[2])
+
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/gotoworld.lua b/MCServer/Plugins/Core/gotoworld.lua
new file mode 100644
index 000000000..d5113b667
--- /dev/null
+++ b/MCServer/Plugins/Core/gotoworld.lua
@@ -0,0 +1,15 @@
+function HandleGotoWorldCommand( Split, Player )
+ if( #Split ~= 2 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /gotoworld [WorldName]" )
+ return true
+ end
+
+ if( Player:MoveToWorld(Split[2]) == false ) then
+ Player:SendMessage( cChatColor.Green .. "Could not move to world '" .. Split[2] .. "'!" )
+ return true
+ end
+
+
+ Player:SendMessage( cChatColor.Green .. "Moved successfully to '" .. Split[2] .. "'! :D" )
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/help.lua b/MCServer/Plugins/Core/help.lua
new file mode 100644
index 000000000..02ef25ebd
--- /dev/null
+++ b/MCServer/Plugins/Core/help.lua
@@ -0,0 +1,54 @@
+function HandleHelpCommand( Split, Player )
+ local PluginManager = cRoot:Get():GetPluginManager()
+
+ local LinesPerPage = 9
+ local CurrentPage = 1
+ local CurrentLine = 0
+
+ if( #Split == 2 ) then
+ CurrentPage = tonumber(Split[2])
+ end
+
+ local Pages = {}
+
+ local PluginList = PluginManager:GetAllPlugins()
+ for i, Plugin in ipairs( PluginList ) do
+ local Commands = Plugin:GetCommands()
+ for i, v in ipairs( Commands ) do
+ if( Player:HasPermission( v.Permission ) ) then
+ local PageNum = math.floor( CurrentLine/LinesPerPage )+1
+ if( Pages[ PageNum ] == nil ) then Pages[ PageNum ] = {} end -- Create page
+
+ if( Pages[ PageNum ].ShownName ~= Plugin:GetName() and SHOW_PLUGIN_NAMES == true ) then
+ if( CurrentLine == LinesPerPage * PageNum -1 ) then -- Don't add if it's the last line of the page, it looks silly
+ -- Add it to the next page instead
+ CurrentLine = CurrentLine+1
+ PageNum = math.floor( CurrentLine/LinesPerPage )+1
+
+ if( Pages[ PageNum ] == nil ) then Pages[ PageNum ] = {} end -- Create page
+ table.insert( Pages[ PageNum ], cChatColor.Gold .. Plugin:GetName() )
+ else
+ Pages[ PageNum ].ShownName = Plugin:GetName()
+ table.insert( Pages[ PageNum ], cChatColor.Gold .. Plugin:GetName() )
+ end
+ CurrentLine = CurrentLine+1
+ PageNum = math.floor( CurrentLine/LinesPerPage )+1
+ if( Pages[ PageNum ] == nil ) then Pages[ PageNum ] = {} end -- Create page
+ end
+ local Message = cChatColor.Blue .. v.Command .. v.Description;
+ table.insert( Pages[ PageNum ], Message )
+ CurrentLine = CurrentLine+1
+ end
+ end
+ end
+
+ Player:SendMessage( cChatColor.Purple .. "- All commands - " .. cChatColor.Gold .. "[Page " .. (CurrentPage) .."/"..#Pages.."]" )
+
+ if( Pages[CurrentPage] ~= nil ) then
+ for i, v in ipairs(Pages[CurrentPage]) do
+ Player:SendMessage( v )
+ end
+ end
+
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/item.lua b/MCServer/Plugins/Core/item.lua
new file mode 100644
index 000000000..942fa8ce6
--- /dev/null
+++ b/MCServer/Plugins/Core/item.lua
@@ -0,0 +1,65 @@
+function HandleItemCommand( Split, Player )
+ if( #Split ~= 2 and #Split ~=3 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /item [ItemID/Name:Dmg] <Amount>" )
+ return true
+ end
+
+ local FoundItem = false
+
+ local ItemSyntax = Split[2] -- Contains item string with optional metadata
+ local ItemData = StringSplit( Split[2], ":" )
+
+ -- Default item values
+ local ItemID = 0
+ local ItemMeta = 0
+ local ItemAmount = 1
+
+ if( #ItemData > 0 ) then
+ ItemID = ItemData[1]
+ end
+
+ if( tonumber(ItemID) ~= nil ) then -- Definitely a number
+ ItemID = tonumber(ItemID)
+ if( IsValidItem( ItemID ) ) then
+ FoundItem = true
+ end
+ end
+
+ if( FoundItem == false ) then
+ if ( HAVE_ITEM_NAMES == true ) then
+ local Item = ItemsTable[ ItemID ]
+ if( Item ~= nil ) then
+ ItemID = Item.m_ItemID
+ ItemMeta = Item.m_ItemHealth
+ FoundItem = true
+ end
+ end
+ end
+
+ -- Override metadata from item in list, if metadata was given
+ if( #ItemData > 1 and tonumber( ItemData[2] ) ~= nil ) then -- Metadata is given, and is a number
+ ItemMeta = tonumber( ItemData[2] )
+ end
+
+ if( FoundItem == false ) then
+ Player:SendMessage( cChatColor.Green .. "Invalid Item ID / Name !" )
+ return true
+ end
+
+ if( #Split == 3 ) then
+ ItemAmount = tonumber( Split[3] )
+ if( ItemAmount == nil or ItemAmount < 1 or ItemAmount > 512 ) then
+ Player:SendMessage( cChatColor.Green .. "Invalid Amount !" )
+ return true
+ end
+ end
+
+ local NewItem = cItem( ItemID, ItemAmount, ItemMeta )
+ if( Player:GetInventory():AddItem( NewItem ) == true ) then
+ Player:SendMessage( cChatColor.Green .. "There you go !" )
+ LOG("Gave " .. Player:GetName() .. " " .. ItemAmount .. " times " .. ItemID .. ":" .. ItemMeta)
+ else
+ Player:SendMessage( cChatColor.Green .. "Not enough space in inventory !" )
+ end
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/kick.lua b/MCServer/Plugins/Core/kick.lua
new file mode 100644
index 000000000..ff4f8a705
--- /dev/null
+++ b/MCServer/Plugins/Core/kick.lua
@@ -0,0 +1,27 @@
+function HandleKickCommand( Split, Player )
+ if( #Split < 2 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /kick [Player] <Reason>" )
+ return true
+ end
+
+ local World = Player:GetWorld()
+ local OtherPlayer = World:GetPlayer( Split[2] )
+ if( OtherPlayer == nil ) then
+ Player:SendMessage( cChatColor.Green .. "Could not find player " .. Split[2] )
+ return true
+ end
+
+ local Reason = "You have been kicked"
+ if( #Split > 2 ) then
+ Reason = table.concat(Split, " ", 3)
+ end
+
+ local Server = cRoot:Get():GetServer()
+ LOGINFO( Player:GetName() .. " is kicking " .. OtherPlayer:GetName() .. " ( "..Reason..") " )
+ Server:SendMessage( "Kicking " .. OtherPlayer:GetName() )
+
+ local ClientHandle = OtherPlayer:GetClientHandle()
+ ClientHandle:Kick( Reason )
+
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/main.lua b/MCServer/Plugins/Core/main.lua
new file mode 100644
index 000000000..fead7638b
--- /dev/null
+++ b/MCServer/Plugins/Core/main.lua
@@ -0,0 +1,147 @@
+---- Some settings -----
+SHOW_PLUGIN_NAMES = true -- If true, plugin name will be shown before commands
+ -- This is overwritten in the Initialize() function
+------------------------
+
+-- Global variables
+PLUGIN = {} -- Reference to own plugin object
+BannedPlayersIni = {}
+WhiteListIni = {}
+ItemsTable = {}
+
+function Initialize( Plugin )
+ PLUGIN = Plugin
+
+ Plugin:SetName( "Core" )
+ Plugin:SetVersion( 8 )
+
+ PluginManager = cRoot:Get():GetPluginManager()
+ PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_JOIN)
+ PluginManager:AddHook(Plugin, cPluginManager.HOOK_LOGIN)
+ PluginManager:AddHook(Plugin, cPluginManager.HOOK_BLOCK_PLACE)
+ PluginManager:AddHook(Plugin, cPluginManager.HOOK_BLOCK_DIG)
+ PluginManager:AddHook(Plugin, cPluginManager.HOOK_KILLED)
+ PluginManager:AddHook(Plugin, cPluginManager.HOOK_CRAFTING_NO_RECIPE)
+
+ Plugin:AddCommand("/help", " - [Page] Show this message", "core.help")
+ Plugin:AddCommand("/pluginlist", " - Show list of plugins", "core.pluginlist")
+ Plugin:AddCommand("/tp", " - [Player] - Teleport yourself to a player", "core.teleport")
+ Plugin:AddCommand("/item", " - [ItemID/Name] <Amount> - Spawn an item for yourself", "core.item")
+ Plugin:AddCommand("/list", " - Shows list of connected players", "core.playerlist")
+ Plugin:AddCommand("/motd", " - Show message of the day", "core.motd")
+ Plugin:AddCommand("/reload", " - Reload all plugins", "core.reload")
+ Plugin:AddCommand("/stop", " - Stops the server", "core.stop")
+ Plugin:AddCommand("/time", " - [Day/Night] - Sets the time of day", "core.time")
+ Plugin:AddCommand("/spawn", " - Return to the spawn", "core.spawn")
+ Plugin:AddCommand("/kick", " - [Player] - Kick a player", "core.kick")
+ Plugin:AddCommand("/ban", " - [Player] - Ban a player", "core.ban")
+ Plugin:AddCommand("/unban", " - [Player] - Unban a player", "core.unban")
+ Plugin:AddCommand("/top", " - Teleport yourself to the top most block", "core.top")
+ Plugin:AddCommand("/gm", " - [Gamemode (0|1)] - Change your gamemode", "core.changegm")
+ Plugin:AddCommand("/gotoworld", " - Move to a different world!", "core.gotoworld")
+ Plugin:AddCommand("/coords", " - Show your current server coordinates", "core.coords")
+ Plugin:AddCommand("/viewdistance", " - [".. cClientHandle.MIN_VIEW_DISTANCE .."-".. cClientHandle.MAX_VIEW_DISTANCE .."] - Change your view distance", "core.viewdistance")
+ Plugin:AddCommand("/regeneratechunk", " - <X [Z]> - Regenerates a chunk", "core.regeneratechunk")
+
+ Plugin:BindCommand( "/help", "core.help", HandleHelpCommand )
+ Plugin:BindCommand( "/pluginlist", "core.pluginlist", HandlePluginListCommand )
+ Plugin:BindCommand( "/tp", "core.teleport", HandleTPCommand )
+ Plugin:BindCommand( "/item", "core.item", HandleItemCommand )
+ Plugin:BindCommand( "/i", "core.item", HandleItemCommand )
+ Plugin:BindCommand( "/list", "core.playerlist", HandlePlayerListCommand )
+ Plugin:BindCommand( "/who", "core.playerlist", HandlePlayerListCommand )
+ Plugin:BindCommand( "/playerlist", "core.playerlist", HandlePlayerListCommand )
+ Plugin:BindCommand( "/motd", "core.motd", HandleMOTDCommand )
+ Plugin:BindCommand( "/reload", "core.reload", HandleReloadCommand )
+ Plugin:BindCommand( "/stop", "core.stop", HandleStopCommand )
+ Plugin:BindCommand( "/time", "core.time", HandleTimeCommand )
+ Plugin:BindCommand( "/spawn", "core.spawn", HandleSpawnCommand )
+ Plugin:BindCommand( "/home", "core.spawn", HandleSpawnCommand )
+ Plugin:BindCommand( "/kick", "core.kick", HandleKickCommand )
+ Plugin:BindCommand( "/ban", "core.ban", HandleBanCommand )
+ Plugin:BindCommand( "/unban", "core.unban", HandleUnbanCommand )
+ Plugin:BindCommand( "/top", "core.top", HandleTopCommand )
+ Plugin:BindCommand( "/gm", "core.changegm", HandleChangeGMCommand )
+ Plugin:BindCommand( "/gotoworld", "core.gotoworld", HandleGotoWorldCommand )
+ Plugin:BindCommand( "/coords", "core.coords", HandleCoordsCommand )
+ Plugin:BindCommand( "/viewdistance", "core.viewdistance", HandleViewDistanceCommand )
+ Plugin:BindCommand( "/regeneratechunk", "core.regeneratechunk", HandleRegenerateChunkCommand )
+
+ local IniFile = cIniFile("settings.ini")
+ if ( IniFile:ReadFile() == true ) then
+ SHOW_PLUGIN_NAMES = IniFile:GetValueB("HelpPlugin", "ShowPluginNames", true )
+ end
+
+ local itemsINI = cIniFile("items.ini")
+ if ( itemsINI:ReadFile() == true ) then
+ local KeyID = itemsINI:FindKey('Items')
+
+ LOGINFO("Core: loaded " .. itemsINI:GetNumValues( KeyID ) .. " item names.")
+
+ for i = 0, itemsINI:GetNumValues('Items') do
+ local ItemName = itemsINI:GetValueName( KeyID, i )
+ local ItemSyntax = itemsINI:GetValue(KeyID, i, "0")
+
+ local ItemData = StringSplit(ItemSyntax, ":") -- [1] = ID, [2] = perhaps meta/dmg
+ if( #ItemData > 0 ) then
+ local ItemID = tonumber( ItemData[1] )
+ if( ItemID > 0 ) then
+ local ItemMeta = 0
+ if( #ItemData > 1 ) then
+ ItemMeta = tonumber( ItemData[2] )
+ end
+ ItemsTable[ ItemName ] = cItem( ItemID, 1, ItemMeta )
+ --LOGINFO("Got item: " .. ItemName .. "-> " .. ItemsTable[ ItemName ].m_ItemID ..":" .. ItemsTable[ ItemName ].m_ItemHealth )
+ end
+ end
+ end
+
+ HAVE_ITEM_NAMES = true
+ end
+
+ -- Load whitelist, and add default values and stuff
+ WhiteListIni = cIniFile("whitelist.ini")
+ if ( WhiteListIni:ReadFile() == true ) then
+ if( WhiteListIni:GetValueB("WhiteListSettings", "WhiteListOn", false) == true ) then
+ if( WhiteListIni:GetNumValues("WhiteList") > 0 ) then
+ LOGINFO("Core: loaded " .. WhiteListIni:GetNumValues('WhiteList') .. " whitelisted players.")
+ else
+ LOGWARN("WARNING: WhiteList is on, but there are no people in the whitelist!")
+ end
+ end
+ else
+ WhiteListIni:SetValueB("WhiteListSettings", "WhiteListOn", false )
+ WhiteListIni:SetValue("WhiteList", "", "") -- So it adds an empty header
+ WhiteListIni:DeleteValue("WhiteList", "") -- And remove the value
+ WhiteListIni:KeyComment("WhiteList", "PlayerName=1")
+ if( WhiteListIni:WriteFile() == false ) then
+ LOGWARN("WARNING: Could not write to whitelist.ini")
+ end
+ end
+
+ -- Load banned players, and add default values and stuff
+ BannedPlayersIni = cIniFile("banned.ini")
+ if ( BannedPlayersIni:ReadFile() == true ) then
+ if( BannedPlayersIni:GetNumValues("Banned") > 0 ) then
+ LOGINFO("Core: loaded " .. BannedPlayersIni:GetNumValues("Banned") .. " banned players.")
+ end
+ else
+ BannedPlayersIni:SetValue("Banned", "", "") -- So it adds an empty header
+ BannedPlayersIni:DeleteValue("Banned", "") -- And remove the value
+ BannedPlayersIni:KeyComment("Banned", "PlayerName=1")
+ if( BannedPlayersIni:WriteFile() == false ) then
+ LOGWARN("WARNING: Could not write to banned.ini")
+ end
+ end
+
+ local WebPlugin = Plugin:CreateWebPlugin()
+ WebPlugin:SetName( Plugin:GetName() )
+ WebPlugin:AddTab( "Playerlist", HandleRequest_PlayerList )
+ WebPlugin:AddTab( "Whitelist", HandleRequest_WhiteList )
+ WebPlugin:AddTab( "Permissions", HandleRequest_Permissions )
+ WebPlugin:AddTab( "Manage Plugins", HandleRequest_ManagePlugins )
+ WebPlugin:AddTab( "Ini Editor", HandleRequest_IniEditor )
+
+ LOG( "Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion() )
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/motd.lua b/MCServer/Plugins/Core/motd.lua
new file mode 100644
index 000000000..49cdcecad
--- /dev/null
+++ b/MCServer/Plugins/Core/motd.lua
@@ -0,0 +1,10 @@
+function HandleMOTDCommand( Split, Player )
+ ShowMOTDTo( Player )
+ return true
+end
+
+function ShowMOTDTo( Player )
+ Player:SendMessage( cChatColor.Gold .. "Welcome to the MCServer test server!" );
+ Player:SendMessage( cChatColor.Gold .. "http://mcserver.ae-c.net/" );
+ Player:SendMessage( cChatColor.Gold .. "Type /help for all commands" );
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/onblockdig.lua b/MCServer/Plugins/Core/onblockdig.lua
new file mode 100644
index 000000000..65e48576c
--- /dev/null
+++ b/MCServer/Plugins/Core/onblockdig.lua
@@ -0,0 +1,10 @@
+function OnBlockDig(Player, BlockX, BlockY, BlockZ, BlockFace, Status, OldBlockType, OldBlockMeta)
+ -- dont check if the direction is in the air
+ if (BlockFace ~= -1) then
+
+ if (Player:HasPermission("core.build") == false) then
+ return true
+ end
+ end
+ return false
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/onblockplace.lua b/MCServer/Plugins/Core/onblockplace.lua
new file mode 100644
index 000000000..9032f8207
--- /dev/null
+++ b/MCServer/Plugins/Core/onblockplace.lua
@@ -0,0 +1,63 @@
+function OnBlockPlace(Player, BlockX, BlockY, BlockZ, BlockFace, HeldItem)
+
+ -- dont check if the direction is in the air
+ if (BlockFace == -1) then
+ return false
+ end
+
+ if( Player:HasPermission("core.build") == false ) then
+ return true
+ end
+
+ -- TODO: If the placed block is not a block (torch etc.), allow it without checking for collisions
+
+ local X = BlockX
+ local Y = BlockY
+ local Z = BlockZ
+ X, Y, Z = AddDirection(X, Y, Z, BlockFace)
+ if (Y >= 256 or Y < 0) then
+ return true
+ end
+
+ local CheckCollision = function(Player)
+ -- drop the decimals, we only care about the full block X,Y,Z
+ local PlayerX = math.floor(Player:GetPosX(), 0)
+ local PlayerY = math.floor(Player:GetPosY(), 0)
+ local PlayerZ = math.floor(Player:GetPosZ(), 0)
+
+ -- player height is 2 blocks, so we check the position and then offset it up one
+ -- so they can't place a block in anyone's face
+
+ local collision = false
+ if ((BlockFace == BLOCK_FACE_TOP) and (PlayerY == BlockY - 2) and (PlayerX == BlockX) and (PlayerZ == BlockZ)) then
+ collision = true
+ end
+
+ if ((BlockFace == BLOCK_FACE_BOTTOM) and (PlayerY == BlockY + 1) and (PlayerX == BlockX) and (PlayerZ == BlockZ)) then
+ collision = true
+ end
+
+ if ((BlockFace == BLOCK_FACE_NORTH) and (PlayerX == BlockX) and (PlayerZ == BlockZ - 1)) then
+ if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end
+ end
+
+ if ((BlockFace == BLOCK_FACE_SOUTH) and (PlayerX == BlockX) and (PlayerZ == BlockZ + 1)) then
+ if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end
+ end
+
+ if ((BlockFace == BLOCK_FACE_WEST) and (PlayerX == BlockX - 1) and (PlayerZ == BlockZ)) then
+ if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end
+ end
+
+ if ((BlockFace == BLOCK_FACE_EAST) and (PlayerX == BlockX + 1) and (PlayerZ == BlockZ)) then
+ if ((PlayerY == BlockY) or (PlayerY + 1 == BlockY)) then collision = true end
+ end
+
+ return collision
+ end
+
+ if (Player:GetWorld():ForEachPlayer(CheckCollision) == false) then
+ return true
+ end
+ return false
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/oncraftingnorecipe.lua b/MCServer/Plugins/Core/oncraftingnorecipe.lua
new file mode 100644
index 000000000..2006e410f
--- /dev/null
+++ b/MCServer/Plugins/Core/oncraftingnorecipe.lua
@@ -0,0 +1,214 @@
+
+-- Implements item-repair using the HOOK_CRAFTING_NO_RECIPE hook
+-- Based on Fixies plugin v2 by Taugeshtu
+
+
+-- how much "extra" points are healed per a repair operation (fraction of full health)
+BONUS = 0.1
+
+
+
+
+
+function OnCraftingNoRecipe(Player, Grid, Recipe)
+ local _do_fix = false
+ local Items = {}
+ for x = 0, Grid:GetWidth() - 1 do
+ for y = 0, Grid:GetHeight() - 1 do
+ local Item = Grid:GetItem(x, y)
+ if (Item.m_ItemID ~= E_ITEM_EMPTY) then
+ table.insert(Items, Item)
+ end
+ end
+ end
+
+ if (#Items ~= 2) then
+ -- Only two items together can be fixed
+ return false
+ end
+
+ if (Items[1].m_ItemID ~= Items[2].m_ItemID) then
+ -- Only items of the same type may be fixed
+ return false
+ end
+
+ if (
+ (Items[1].m_ItemHealth == 0) or
+ (Items[2].m_ItemHealth == 0)
+ )
+ then
+ -- Only damaged items may be fixed
+ return false
+ end
+
+ local _ID = Items[1].m_ItemID
+ local _least_hp = math.max(Items[1].m_ItemHealth, Items[2].m_ItemHealth)
+ local _most_hp = math.min(Items[1].m_ItemHealth, Items[2].m_ItemHealth)
+ local _item_hp = 0
+
+ -- TODO: This could be refactored into better code, using an _ID-indexed table for _item_hp
+
+ if (
+ (_ID == E_ITEM_WOODEN_SHOVEL) or
+ (_ID == E_ITEM_WOODEN_AXE) or
+ (_ID == E_ITEM_WOODEN_PICKAXE) or
+ (_ID == E_ITEM_WOODEN_SWORD) or
+ (_ID == E_ITEM_WOODEN_HOE)
+ )
+ then
+ _item_hp = 60
+ _do_fix = true
+ end
+
+ if (
+ (_ID == E_ITEM_STONE_SHOVEL) or
+ (_ID == E_ITEM_STONE_AXE) or
+ (_ID == E_ITEM_STONE_PICKAXE) or
+ (_ID == E_ITEM_STONE_SWORD) or
+ (_ID == E_ITEM_STONE_HOE)
+ )
+ then
+ _item_hp = 132
+ _do_fix = true
+ end
+
+ if (
+ (_ID == E_ITEM_IRON_SHOVEL) or
+ (_ID == E_ITEM_IRON_AXE) or
+ (_ID == E_ITEM_IRON_PICKAXE) or
+ (_ID == E_ITEM_IRON_SWORD) or
+ (_ID == E_ITEM_IRON_HOE)
+ )
+ then
+ _item_hp = 251
+ _do_fix = true
+ end
+
+ if (
+ (_ID == E_ITEM_GOLD_SHOVEL) or
+ (_ID == E_ITEM_GOLD_AXE) or
+ (_ID == E_ITEM_GOLD_PICKAXE) or
+ (_ID == E_ITEM_GOLD_SWORD) or
+ (_ID == E_ITEM_GOLD_HOE)
+ )
+ then
+ _item_hp = 33
+ _do_fix = true
+ end
+
+ if (
+ (_ID == E_ITEM_DIAMOND_SHOVEL) or
+ (_ID == E_ITEM_DIAMOND_AXE) or
+ (_ID == E_ITEM_DIAMOND_PICKAXE) or
+ (_ID == E_ITEM_DIAMOND_SWORD) or
+ (_ID == E_ITEM_DIAMOND_HOE)
+ )
+ then
+ _item_hp = 1562
+ _do_fix = true
+ end
+
+ if (_ID == E_ITEM_LEATHER_CAP) then
+ _item_hp = 56
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_LEATHER_TUNIC) then
+ _item_hp = 82
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_LEATHER_PANTS) then
+ _item_hp = 76
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_LEATHER_BOOTS) then
+ _item_hp = 66
+ _do_fix = true
+ end
+
+
+ if (_ID == E_ITEM_CHAIN_HELMET) then
+ _item_hp = 78
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_CHAIN_CHESTPLATE) then
+ _item_hp = 114
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_CHAIN_LEGGINGS) then
+ _item_hp = 106
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_CHAIN_BOOTS) then
+ _item_hp = 92
+ _do_fix = true
+ end
+
+
+ if (_ID == E_ITEM_IRON_HELMET) then
+ _item_hp = 166
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_IRON_CHESTPLATE) then
+ _item_hp = 242
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_IRON_LEGGINGS) then
+ _item_hp = 226
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_IRON_BOOTS) then
+ _item_hp = 196
+ _do_fix = true
+ end
+
+
+ if (_ID == E_ITEM_GOLD_HELMET) then
+ _item_hp = 78
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_GOLD_CHESTPLATE) then
+ _item_hp = 114
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_GOLD_LEGGINGS) then
+ _item_hp = 106
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_GOLD_BOOTS) then
+ _item_hp = 92
+ _do_fix = true
+ end
+
+
+ if (_ID == E_ITEM_DIAMOND_HELMET) then
+ _item_hp = 364
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_DIAMOND_CHESTPLATE)then
+ _item_hp = 529
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_DIAMOND_LEGGINGS) then
+ _item_hp = 496
+ _do_fix = true
+ end
+ if (_ID == E_ITEM_DIAMOND_BOOTS) then
+ _item_hp = 430
+ _do_fix = true
+ end
+ -- /////////////////////////////////////////////////////
+
+ if (_do_fix == true) then
+ local _hp = _most_hp - (_item_hp - _least_hp) - _item_hp * BONUS
+ _hp = math.max(_hp, 0)
+ Recipe:SetResult(_ID, 1, _hp)
+ Recipe:SetIngredient(Items[1].x, Items[1].y, Items[1]);
+ Recipe:SetIngredient(Items[2].x, Items[2].y, Items[2]);
+ return true
+ end
+ return false
+end
+
+
+
+
diff --git a/MCServer/Plugins/Core/onkilled.lua b/MCServer/Plugins/Core/onkilled.lua
new file mode 100644
index 000000000..a8a92f667
--- /dev/null
+++ b/MCServer/Plugins/Core/onkilled.lua
@@ -0,0 +1,24 @@
+function OnKilled( Killed, Killer )
+ if( Killer == nil ) then
+ local KilledPlayer = tolua.cast( Killed, "cPlayer")
+ if( not KilledPlayer:IsA("cPlayer") or KilledPlayer == nil ) then
+ return false
+ end
+
+ local Server = cRoot:Get():GetServer()
+ Server:SendMessage( cChatColor.Red .. KilledPlayer:GetName() .. " died" )
+ else
+ local KilledPlayer = tolua.cast( Killed, "cPlayer")
+ if( not KilledPlayer:IsA("cPlayer") or KilledPlayer == nil ) then
+ return false
+ end
+ local KillerPlayer = tolua.cast( Killer, "cPlayer")
+ if( not KillerPlayer:IsA("cPlayer") or KillerPlayer == nil ) then
+ return false
+ end
+
+ local Server = cRoot:Get():GetServer()
+ Server:SendMessage( cChatColor.Red .. KilledPlayer:GetName() .. " was killed by " .. KillerPlayer:GetName() .. "!" )
+ end
+ return false
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/onlogin.lua b/MCServer/Plugins/Core/onlogin.lua
new file mode 100644
index 000000000..a706f8024
--- /dev/null
+++ b/MCServer/Plugins/Core/onlogin.lua
@@ -0,0 +1,20 @@
+function OnLogin( PacketData )
+ if( PacketData.m_Username ~= "" ) then
+ if( BannedPlayersIni:GetValueB("Banned", PacketData.m_Username, false) == true ) then
+ local Server = cRoot:Get():GetServer()
+ Server:SendMessage( PacketData.m_Username .. " tried to join, but is banned!" )
+ LOGINFO( PacketData.m_Username .. " tried to join, but is banned!")
+ return true -- Player is banned, return true to deny access
+ end
+ if( WhiteListIni:GetValueB("WhiteListSettings", "WhiteListOn", false ) == true ) then
+ if( WhiteListIni:GetValueB("WhiteList", PacketData.m_Username, false ) == false ) then -- not on whitelist
+ local Server = cRoot:Get():GetServer()
+ Server:SendMessage( PacketData.m_Username .. " tried to join, but is not on the whitelist." )
+ LOGINFO( PacketData.m_Username .. " tried to join, but is not on the whitelist." )
+ return true -- Deny access to the server
+ end
+ end
+ end
+
+ return false
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/onplayerjoin.lua b/MCServer/Plugins/Core/onplayerjoin.lua
new file mode 100644
index 000000000..e8263f608
--- /dev/null
+++ b/MCServer/Plugins/Core/onplayerjoin.lua
@@ -0,0 +1,4 @@
+function OnPlayerJoin( Player )
+ ShowMOTDTo( Player )
+ return false
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/playerlist.lua b/MCServer/Plugins/Core/playerlist.lua
new file mode 100644
index 000000000..f06dfed85
--- /dev/null
+++ b/MCServer/Plugins/Core/playerlist.lua
@@ -0,0 +1,14 @@
+function HandlePlayerListCommand( Split, Player )
+
+ local PlayerTable = {}
+ local AppendToTable = function( Player )
+ table.insert(PlayerTable, Player:GetName() )
+ end
+ Player:GetWorld():ForEachPlayer( AppendToTable )
+
+ local Message = cChatColor.Green .. "Connected players: (".. cChatColor.White.. #PlayerTable .. cChatColor.Green .. ")"
+ Player:SendMessage( Message )
+
+ Player:SendMessage( table.concat(PlayerTable, " ") )
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/pluginlist.lua b/MCServer/Plugins/Core/pluginlist.lua
new file mode 100644
index 000000000..7b007f7db
--- /dev/null
+++ b/MCServer/Plugins/Core/pluginlist.lua
@@ -0,0 +1,13 @@
+function HandlePluginListCommand( Split, Player )
+ local PluginManager = cRoot:Get():GetPluginManager()
+ local PluginList = PluginManager:GetAllPlugins()
+
+ local PluginTable = {}
+ for i, Plugin in ipairs( PluginList ) do
+ table.insert(PluginTable, Plugin:GetName() )
+ end
+
+ Player:SendMessage( cChatColor.Green .. "Loaded plugins: (" .. #PluginTable .. ")" )
+ Player:SendMessage( cChatColor.Gold .. table.concat(PluginTable, cChatColor.Gold.." ") )
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/regeneratechunk.lua b/MCServer/Plugins/Core/regeneratechunk.lua
new file mode 100644
index 000000000..b4b2874fc
--- /dev/null
+++ b/MCServer/Plugins/Core/regeneratechunk.lua
@@ -0,0 +1,18 @@
+function HandleRegenerateChunkCommand( Split, Player )
+ if( (#Split == 2) or (#Split > 3) ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /regeneratechunk <X [Z]>" )
+ return true
+ end
+
+ local X = Player:GetChunkX()
+ local Z = Player:GetChunkZ()
+
+ if( #Split == 3 ) then
+ X = Split[2]
+ Z = Split[3]
+ end
+
+ Player:SendMessage(cChatColor.Green .. "Regenerating chunk ["..X..", "..Z.."]")
+ Player:GetWorld():RegenerateChunk(X, Z)
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/reload.lua b/MCServer/Plugins/Core/reload.lua
new file mode 100644
index 000000000..e2b338ba1
--- /dev/null
+++ b/MCServer/Plugins/Core/reload.lua
@@ -0,0 +1,6 @@
+function HandleReloadCommand( Split, Player )
+ Server = cRoot:Get():GetServer()
+ Server:SendMessage( cChatColor.Green .. "Reloading all plugins." )
+ cRoot:Get():GetPluginManager():ReloadPlugins()
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/spawn.lua b/MCServer/Plugins/Core/spawn.lua
new file mode 100644
index 000000000..73034d9cf
--- /dev/null
+++ b/MCServer/Plugins/Core/spawn.lua
@@ -0,0 +1,6 @@
+function HandleSpawnCommand( Split, Player )
+ World = Player:GetWorld()
+ Player:TeleportTo( World:GetSpawnX(), World:GetSpawnY(), World:GetSpawnZ() )
+ LOGINFO( Player:GetName() .. " returned to spawn." )
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/stop.lua b/MCServer/Plugins/Core/stop.lua
new file mode 100644
index 000000000..0a06fc7d3
--- /dev/null
+++ b/MCServer/Plugins/Core/stop.lua
@@ -0,0 +1,6 @@
+function HandleStopCommand( Split, Player )
+ Server = cRoot:Get():GetServer()
+ Server:SendMessage( cChatColor.Green .. "Stopping the server..." )
+ cRoot:Get():ServerCommand("stop")
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/teleport.lua b/MCServer/Plugins/Core/teleport.lua
new file mode 100644
index 000000000..90eb3529a
--- /dev/null
+++ b/MCServer/Plugins/Core/teleport.lua
@@ -0,0 +1,23 @@
+function HandleTPCommand( Split, Player )
+ if( #Split ~= 2 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /tp [PlayerName]" )
+ return true
+ end
+
+ World = Player:GetWorld()
+
+ local TeleportDestination = function(OtherPlayer)
+ if( OtherPlayer == Player ) then
+ Player:SendMessage( cChatColor.Green .. "Already there :)" )
+ else
+ Player:TeleportToEntity( OtherPlayer )
+ Player:SendMessage( cChatColor.Green .. "You teleported to "..OtherPlayer:GetName().."!" )
+ OtherPlayer:SendMessage( cChatColor.Green .. Player:GetName().." teleported to you!" )
+ end
+ end
+
+ if (not(World:DoWithPlayer(Split[2], TeleportDestination))) then
+ Player:SendMessage( cChatColor.Green .. "Can't find player " .. Split[2] )
+ end
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/time.lua b/MCServer/Plugins/Core/time.lua
new file mode 100644
index 000000000..425d69e6a
--- /dev/null
+++ b/MCServer/Plugins/Core/time.lua
@@ -0,0 +1,18 @@
+function HandleTimeCommand( Split, Player )
+ if( #Split ~= 2 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /time [Day/Night]" )
+ return true;
+ end
+
+ local Server = cRoot:Get():GetServer()
+ if( string.upper( Split[2] ) == "DAY") then
+ Player:GetWorld():SetWorldTime( 0 )
+ Server:SendMessage( cChatColor.Green .. Player:GetName() .. " set the time to Day.")
+ elseif( string.upper( Split[2] ) == "NIGHT") then
+ Player:GetWorld():SetWorldTime( 12000 + 1000 )
+ Server:SendMessage( cChatColor.Green .. Player:GetName() .. " set the time to Night.")
+ else
+ Player:SendMessage( cChatColor.Green .. "Usage: /time [Day/Night]" )
+ end
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/top.lua b/MCServer/Plugins/Core/top.lua
new file mode 100644
index 000000000..0f7a8f95f
--- /dev/null
+++ b/MCServer/Plugins/Core/top.lua
@@ -0,0 +1,11 @@
+function HandleTopCommand( Split, Player )
+ local World = Player:GetWorld()
+
+ local PlayerPos = Player:GetPosition()
+ local Height = World:GetHeight( math.floor(PlayerPos.x), math.floor(PlayerPos.z) )
+
+ Player:TeleportTo( PlayerPos.x, Height+1, PlayerPos.z )
+ Player:SendMessage("Teleported to the top block")
+
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/unban.lua b/MCServer/Plugins/Core/unban.lua
new file mode 100644
index 000000000..9defbe323
--- /dev/null
+++ b/MCServer/Plugins/Core/unban.lua
@@ -0,0 +1,20 @@
+function HandleUnbanCommand( Split, Player )
+ if( #Split < 2 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /unban [Player]" )
+ return true
+ end
+
+ if( BannedPlayersIni:GetValueB("Banned", Split[2], false) == false ) then
+ Player:SendMessage( cChatColor.Green .. Split[2] .. " is not banned!" )
+ return true
+ end
+
+ BannedPlayersIni:SetValueB("Banned", Split[2], false, false)
+ BannedPlayersIni:WriteFile()
+
+ local Server = cRoot:Get():GetServer()
+ LOGINFO( Player:GetName() .. " is unbanning " .. Split[2] )
+ Server:SendMessage( "Unbanning " .. Split[2] )
+
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/viewdistance.lua b/MCServer/Plugins/Core/viewdistance.lua
new file mode 100644
index 000000000..43d2a7de8
--- /dev/null
+++ b/MCServer/Plugins/Core/viewdistance.lua
@@ -0,0 +1,10 @@
+function HandleViewDistanceCommand( Split, Player )
+ if( #Split ~= 2 ) then
+ Player:SendMessage( cChatColor.Green .. "Usage: /viewdistance [".. cClientHandle.MIN_VIEW_DISTANCE .."-".. cClientHandle.MAX_VIEW_DISTANCE .."]" )
+ return true
+ end
+
+ Player:GetClientHandle():SetViewDistance( Split[2] )
+ Player:SendMessage(cChatColor.Green .. "Your viewdistance has been set to " .. Player:GetClientHandle():GetViewDistance() )
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/web_manageplugins.lua b/MCServer/Plugins/Core/web_manageplugins.lua
new file mode 100644
index 000000000..3030efc7a
--- /dev/null
+++ b/MCServer/Plugins/Core/web_manageplugins.lua
@@ -0,0 +1,93 @@
+local function Button_RemovePlugin( Name, Index )
+ return "<form method='POST'><input type='hidden' name='PluginName' value='"..Name.."'><input type='hidden' name='PluginIndex' value='"..Index.."'><input type='submit' name='RemovePlugin' value='Remove'></form>"
+end
+
+local function HandlePluginListChanges( Request, SettingsIni )
+ local Content = ""
+ if( Request.PostParams["RemovePlugin"] ~= nil
+ and Request.PostParams["PluginName"] ~= nil
+ and Request.PostParams["PluginIndex"] ~= nil ) then -- Removing a plugin
+
+ local KeyIdx = SettingsIni:FindKey("Plugins")
+ local PluginIdx = Request.PostParams["PluginIndex"]
+
+ local PluginName = SettingsIni:GetValue( KeyIdx, PluginIdx )
+ if( (PluginName == Request.PostParams["PluginName"]) and (SettingsIni:DeleteValueByID( KeyIdx, PluginIdx ) == true) ) then
+ SettingsIni:WriteFile()
+ Content = "Removed plugin '" .. PluginName .. "'"
+ else
+ Content = "Whoops! Something went wrong!"
+ end
+
+
+ elseif( Request.PostParams["AddPlugin"] ~= nil
+ and Request.PostParams["PluginName"] ~= nil ) then -- Add a plugin
+
+ SettingsIni:SetValue("Plugins", "NewPlugin", Request.PostParams["PluginName"], true )
+ SettingsIni:WriteFile()
+
+ Content = "Added plugin '".. Request.PostParams["PluginName"] .."'"
+
+ end
+
+ if( #Content > 0 ) then
+ return "<p><font color='red'><strong>INFO: " .. Content .. "</strong></font></p>"
+ else
+ return ""
+ end
+end
+
+function HandleRequest_ManagePlugins( Request )
+ local Content = ""
+
+ if( Request.PostParams["reload"] ~= nil ) then
+ Content = Content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
+ Content = Content .. "<p>Reloading plugins... This can take a while depending on the plugins you're using.</p>"
+ cRoot:Get():GetPluginManager():ReloadPlugins()
+ return Content
+ end
+
+ local PluginManager = cRoot:Get():GetPluginManager()
+ local PluginList = PluginManager:GetAllPlugins()
+
+ Content = Content .. "<h4>Currently active plugins</h4>"
+ Content = Content .. "<table>"
+ for k, Plugin in pairs(PluginList) do
+ Content = Content .. "<tr><td>" .. Plugin:GetName() .. " V. " .. Plugin:GetVersion() .. "</td></tr>"
+ end
+ Content = Content .. "</table>"
+
+ local SettingsIni = cIniFile("settings.ini")
+ if( SettingsIni:ReadFile() == true ) then
+ Content = Content .. "<h4>Plugins according to settings.ini</h4>"
+
+ Content = Content .. HandlePluginListChanges( Request, SettingsIni )
+
+ Content = Content .. "<table>"
+
+ local KeyIdx = SettingsIni:FindKey("Plugins")
+ local NumValues = SettingsIni:GetNumValues( KeyIdx )
+ for i = 0, NumValues-1 do
+ local ValueName = SettingsIni:GetValueName(KeyIdx, i )
+ local PluginName = SettingsIni:GetValue(KeyIdx, i)
+ Content = Content .. "<tr>"
+ Content = Content .. "<td>" .. ValueName .. ": " .. PluginName .. "</td>"
+ Content = Content .. "<td>" .. Button_RemovePlugin( PluginName, i ) .. "</td>"
+ Content = Content .. "</tr>"
+ end
+ Content = Content .. "</table>"
+ end
+
+ Content = Content .. "<h4>Add plugin to settings.ini</h4>"
+ Content = Content .. "<form method='POST'>"
+ Content = Content .. "<input type='text' name='PluginName'><input type='submit' name='AddPlugin' value='Add Plugin'>"
+ Content = Content .. "</form>"
+
+ Content = Content .. "<h4>Reload</h4>"
+ Content = Content .. "<form method='POST'>"
+ Content = Content .. "<p>Click the reload button to reload all plugins!<br>"
+ Content = Content .. "<input type='submit' name='reload' value='Reload!'></p>"
+ Content = Content .. "</form>"
+
+ return Content
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/web_permissions.lua b/MCServer/Plugins/Core/web_permissions.lua
new file mode 100644
index 000000000..4fce502e1
--- /dev/null
+++ b/MCServer/Plugins/Core/web_permissions.lua
@@ -0,0 +1,79 @@
+local function ShowUsersTable()
+ local Content = "<h4>Users</h4>"
+
+ local UsersIni = cIniFile("users.ini")
+ if( UsersIni:ReadFile() == false ) then
+ return "Could not read users.ini!"
+ end
+
+ local NumUsers = UsersIni:GetNumKeys()
+
+ Content = Content .. "<table>"
+
+ if( NumUsers > 0 ) then
+ Content = Content .. "<tr><th></th><th>User</th><th>Groups</th></tr>"
+
+ for i=0, NumUsers-1 do
+ local UserName = UsersIni:GetKeyName( i )
+
+ Content = Content .. "<tr>"
+ Content = Content .. "<td style='width: 10px;'>" .. i .. ".</td>"
+ Content = Content .. "<td>" .. UserName .. "</td>"
+ Content = Content .. "<td>"
+ Content = Content .. UsersIni:GetValue( UserName, "Groups", "-" )
+ Content = Content .. "</td>"
+ Content = Content .. "</tr>"
+ end
+ else
+ Content = Content .. "<tr><td>None</td></tr>"
+ end
+ Content = Content .. "</table>"
+
+
+ return Content
+end
+
+local function ShowGroupsTable()
+ local Content = "<h4>Groups</h4>"
+
+ local GroupsIni = cIniFile("groups.ini")
+ if( GroupsIni:ReadFile() == false ) then
+ return "Could not read groups.ini!"
+ end
+
+ local NumGroups = GroupsIni:GetNumKeys()
+
+ Content = Content .. "<table>"
+ if( NumGroups > 0 ) then
+ Content = Content .. "<tr><th></th><th>Name</th><th>Permissions</th><th>Color</th></tr>"
+
+ for i=0, NumGroups-1 do
+ local GroupName = GroupsIni:GetKeyName( i )
+
+ Content = Content .. "<tr>"
+ Content = Content .. "<td style='width: 10px;'>" .. i .. ".</td>"
+ Content = Content .. "<td>" .. GroupName .. "</td>"
+ Content = Content .. "<td>"
+ Content = Content .. GroupsIni:GetValue( GroupName, "Permissions", "-" )
+ Content = Content .. "</td>"
+ Content = Content .. "<td>"
+ Content = Content .. GroupsIni:GetValue( GroupName, "Color", "-" )
+ Content = Content .. "</td>"
+ Content = Content .. "</tr>"
+ end
+ else
+ Content = Content .. "<tr><td>None</td></tr>"
+ end
+ Content = Content .. "</table>"
+
+ return Content
+end
+
+function HandleRequest_Permissions( Request )
+ local Content = ""
+
+ Content = Content .. ShowGroupsTable()
+ Content = Content .. ShowUsersTable()
+
+ return Content
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/web_playerlist.lua b/MCServer/Plugins/Core/web_playerlist.lua
new file mode 100644
index 000000000..b7e48cc3f
--- /dev/null
+++ b/MCServer/Plugins/Core/web_playerlist.lua
@@ -0,0 +1,36 @@
+function HandleRequest_PlayerList( Request )
+ local World = cRoot:Get():GetDefaultWorld()
+ local Content = ""
+
+ if( Request.Params["playerlist-kick"] ~= nil ) then
+ local KickPlayerName = Request.Params["playerlist-kick"]
+ local Player = World:GetPlayer( KickPlayerName )
+ if( Player == nil ) then
+ Content = Content .. "<p>Could not find player " .. KickPlayerName .. " !</p>"
+ elseif( Player:GetName() == KickPlayerName ) then
+ Player:GetClientHandle():Kick("You were kicked from the game!")
+ Content = Content .. "<p>" .. KickPlayerName .. " has been kicked from the game!</p>"
+ end
+ end
+
+ Content = Content .. "<p>Connected Players: <b>" .. World:GetNumPlayers() .. "</b></p>"
+ Content = Content .. "<table>"
+
+ local PlayerNum = 0
+ local AddPlayerToTable = function( Player )
+ PlayerNum = PlayerNum + 1
+ Content = Content .. "<tr>"
+ Content = Content .. "<td style='width: 10px;'>" .. PlayerNum .. ".</td>"
+ Content = Content .. "<td>" .. Player:GetName() .. "</td>"
+ Content = Content .. "<td><a href='?playerlist-kick=" .. Player:GetName() .. "'>Kick</a></td>"
+ Content = Content .. "</tr>"
+ end
+ World:ForEachPlayer( AddPlayerToTable )
+
+ if( PlayerNum == 0 ) then
+ Content = Content .. "<tr><td>None</td></tr>"
+ end
+ Content = Content .. "</table>"
+ Content = Content .. "<br>"
+ return Content
+end \ No newline at end of file
diff --git a/MCServer/Plugins/Core/web_whitelist.lua b/MCServer/Plugins/Core/web_whitelist.lua
new file mode 100644
index 000000000..2c9ddb953
--- /dev/null
+++ b/MCServer/Plugins/Core/web_whitelist.lua
@@ -0,0 +1,79 @@
+local function HTMLDeleteButton( name )
+ return "<form method=\"POST\"><input type=\"hidden\" name=\"whitelist-delete\" value=\"".. name .."\"><input type=\"submit\" value=\"Remove from whitelist\"></form>"
+end
+
+function HandleRequest_WhiteList( Request )
+ local UpdateMessage = ""
+ if( Request.PostParams["whitelist-add"] ~= nil ) then
+ local PlayerName = Request.PostParams["whitelist-add"]
+
+ if( WhiteListIni:GetValueB("WhiteList", PlayerName, false) == true ) then
+ UpdateMessage = "<b>".. PlayerName.."</b> is already on the whitelist"
+ else
+ WhiteListIni:SetValueB("WhiteList", PlayerName, true )
+ UpdateMessage = "Added <b>" .. PlayerName .. "</b> to whitelist."
+ WhiteListIni:WriteFile()
+ end
+ elseif( Request.PostParams["whitelist-delete"] ~= nil ) then
+ local PlayerName = Request.PostParams["whitelist-delete"]
+ WhiteListIni:DeleteValue( "WhiteList", PlayerName )
+ UpdateMessage = "Removed <b>" .. PlayerName .. "</b> from whitelist."
+ WhiteListIni:WriteFile()
+ elseif( Request.PostParams["whitelist-reload"] ~= nil ) then
+ WhiteListIni:Erase() -- Empty entire loaded ini first, otherwise weird shit goes down
+ WhiteListIni:ReadFile()
+ UpdateMessage = "Loaded from disk"
+ elseif( Request.Params["whitelist-setenable"] ~= nil ) then
+ local Enabled = Request.Params["whitelist-setenable"]
+ local CreateNewValue = false
+ if( WhiteListIni:FindValue( WhiteListIni:FindKey("WhiteListSettings"), "WhiteListOn" ) == cIniFile.noID ) then -- Find out whether the value is in the ini
+ CreateNewValue = true
+ end
+
+ if( Enabled == "1" ) then
+ WhiteListIni:SetValueB("WhiteListSettings", "WhiteListOn", true, CreateNewValue )
+ else
+ WhiteListIni:SetValueB("WhiteListSettings", "WhiteListOn", false, CreateNewValue )
+ end
+ WhiteListIni:WriteFile()
+ end
+
+
+ local Content = ""
+
+ local WhiteListEnabled = WhiteListIni:GetValueB("WhiteListSettings", "WhiteListOn", false)
+ if( WhiteListEnabled == false ) then
+ Content = Content .. "<p>Whitelist is currently disabled! Click <a href='?whitelist-setenable=1'>here</a> to enable.</p>"
+ end
+
+
+ Content = Content .. "<h4>Whitelisted players</h4>"
+ Content = Content .. "<table>"
+ local KeyNum = WhiteListIni:FindKey("WhiteList")
+ local NumValues = WhiteListIni:GetNumValues(KeyNum)
+ if( NumValues > 0 ) then
+ for Num = 0, NumValues-1 do
+ if( WhiteListIni:GetValue(KeyNum, Num, "0") == "1" ) then
+ local PlayerName = WhiteListIni:GetValueName(KeyNum, Num )
+ Content = Content .. "<tr><td>" .. PlayerName .. "</td><td>" .. HTMLDeleteButton( PlayerName ) .. "</td></tr>"
+ end
+ end
+ else
+ Content = Content .. "<tr><td>None</td></tr>"
+ end
+ Content = Content .. "</table>"
+ Content = Content .. "<br><h4>Add player to whitelist</h4>"
+ Content = Content .. "<form method=\"POST\">"
+ Content = Content .. "<input type=\"text\" name=\"whitelist-add\"><input type=\"submit\" value=\"Add player\">"
+ Content = Content .. "</form>"
+ Content = Content .. "<form method=\"POST\">"
+ Content = Content .. "<input type=\"submit\" name=\"whitelist-reload\" value=\"Reload from disk\">"
+ Content = Content .. "</form>"
+ Content = Content .. "<br>"..UpdateMessage
+
+ if( WhiteListEnabled == true ) then
+ Content = Content .. "<br><br><p>Whitelist is currently enabled, click <a href='?whitelist-setenable=0'>here</a> to disable.</p>"
+ end
+
+ return Content
+end \ No newline at end of file
diff --git a/MCServer/Plugins/MagicCarpet/objects.lua b/MCServer/Plugins/MagicCarpet/objects.lua
new file mode 100644
index 000000000..30528cc42
--- /dev/null
+++ b/MCServer/Plugins/MagicCarpet/objects.lua
@@ -0,0 +1,97 @@
+-- Location object
+cLocation = {}
+function cLocation:new( x, y, z )
+ local object = { x = x, y = y, z = z }
+ setmetatable(object, { __index = cLocation })
+ return object
+end
+
+-- Offsets
+cFibers = { }
+function cFibers:new()
+ local object = {
+ cLocation:new( 2, -1, 2 ),
+ cLocation:new( 2, -1, 1 ),
+ cLocation:new( 2, -1, 0 ),
+ cLocation:new( 2, -1, -1 ),
+ cLocation:new( 2, -1, -2 ),
+ cLocation:new( 1, -1, 2 ),
+ cLocation:new( 1, -1, 1 ),
+ cLocation:new( 1, -1, 0 ),
+ cLocation:new( 1, -1, -1 ),
+ cLocation:new( 1, -1, -2 ),
+ cLocation:new( 0, -1, 2 ),
+ cLocation:new( 0, -1, 1 ),
+ cLocation:new( 0, -1, 0 ),
+ cLocation:new( 0, -1, -1 ),
+ cLocation:new( 0, -1, -2 ),
+ cLocation:new( -1, -1, 2 ),
+ cLocation:new( -1, -1, 1 ),
+ cLocation:new( -1, -1, 0 ),
+ cLocation:new( -1, -1, -1 ),
+ cLocation:new( -1, -1, -2 ),
+ cLocation:new( -2, -1, 2 ),
+ cLocation:new( -2, -1, 1 ),
+ cLocation:new( -2, -1, 0 ),
+ cLocation:new( -2, -1, -1 ),
+ cLocation:new( -2, -1, -2 ),
+ imadeit = false,
+ }
+ setmetatable(object, { __index = cFibers })
+ return object;
+end
+
+-- Carpet object
+cCarpet = {}
+function cCarpet:new()
+ local object = { Location = cLocation:new(0,0,0),
+ Fibers = cFibers:new(),
+ }
+ setmetatable(object, { __index = cCarpet })
+ return object
+end
+
+function cCarpet:remove()
+ local World = cRoot:Get():GetWorld()
+ for i, fib in ipairs( self.Fibers ) do
+ local x = self.Location.x + fib.x
+ local y = self.Location.y + fib.y
+ local z = self.Location.z + fib.z
+ local BlockID = World:GetBlock( x, y, z )
+ if( fib.imadeit == true and BlockID == E_BLOCK_GLASS ) then
+ World:SetBlock( x, y, z, 0, 0 )
+ fib.imadeit = false
+ end
+ end
+end
+
+function cCarpet:draw()
+ local World = cRoot:Get():GetWorld()
+ for i, fib in ipairs( self.Fibers ) do
+ local x = self.Location.x + fib.x
+ local y = self.Location.y + fib.y
+ local z = self.Location.z + fib.z
+ local BlockID = World:GetBlock( x, y, z )
+ if( BlockID == 0 ) then
+ fib.imadeit = true
+ World:SetBlock( x, y, z, E_BLOCK_GLASS, 0 )
+ else
+ fib.imadeit = false
+ end
+ end
+end
+
+function cCarpet:moveTo( NewPos )
+ local x = math.floor( NewPos.x )
+ local y = math.floor( NewPos.y )
+ local z = math.floor( NewPos.z )
+ if( self.Location.x ~= x or self.Location.y ~= y or self.Location.z ~= z ) then
+ self:remove()
+ self.Location = cLocation:new( x, y, z )
+ self:draw()
+ end
+end
+
+function cCarpet:getY()
+ return self.Location.y
+end \ No newline at end of file
diff --git a/MCServer/Plugins/MagicCarpet/plugin.lua b/MCServer/Plugins/MagicCarpet/plugin.lua
new file mode 100644
index 000000000..22604c9d9
--- /dev/null
+++ b/MCServer/Plugins/MagicCarpet/plugin.lua
@@ -0,0 +1,65 @@
+local PLUGIN = {}
+local Carpets = {}
+
+function Initialize( Plugin )
+ PLUGIN = Plugin
+
+ Plugin:SetName( "MagicCarpet" )
+ Plugin:SetVersion( 1 )
+
+ PluginManager = cRoot:Get():GetPluginManager()
+ PluginManager:AddHook( Plugin, cPluginManager.E_PLUGIN_PLAYER_MOVE)
+ PluginManager:AddHook( Plugin, cPluginManager.E_PLUGIN_DISCONNECT)
+
+ Plugin:AddCommand("/mc", " - Spawns a magical carpet!", "magiccarpet")
+ Plugin:BindCommand( "/mc", "magiccarpet", HandleCarpetCommand )
+
+ Log( "Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion() )
+ return true
+end
+
+function OnDisable()
+ Log( PLUGIN:GetName() .. " v." .. PLUGIN:GetVersion() .. " is shutting down..." )
+ for i, Carpet in pairs( Carpets ) do
+ Carpet:remove()
+ end
+end
+
+function HandleCarpetCommand( Split, Player )
+ Carpet = Carpets[ Player ]
+ if( Carpet == nil ) then
+ Carpets[ Player ] = cCarpet:new()
+ Player:SendMessage("You're on a magic carpet!" )
+ else
+ Carpet:remove()
+ Carpets[ Player ] = nil
+ Player:SendMessage("The carpet vanished!" )
+ end
+
+ return true
+end
+
+function OnDisconnect( Reason, Player )
+ local Carpet = Carpets[ Player ]
+ if( Carpet ~= nil ) then
+ Carpet:remove()
+ end
+ Carpets[ Player ] = nil
+end
+
+function OnPlayerMove( Player )
+ local Carpet = Carpets[ Player ]
+ if( Carpet == nil ) then
+ return
+ end
+
+ if( Player:GetPitch() == 90 ) then
+ Carpet:moveTo( cLocation:new( Player:GetPosX(), Player:GetPosY()-1, Player:GetPosZ() ) )
+ else
+ if( Player:GetPosY() < Carpet:getY() ) then
+ LOGINFO("Fell tru mc!")
+ Player:TeleportTo( Player:GetPosX(), Carpet:getY(), Player:GetPosZ() )
+ end
+ Carpet:moveTo( cLocation:new( Player:GetPosX(), Player:GetPosY(), Player:GetPosZ() ) )
+ end
+end \ No newline at end of file
diff --git a/MCServer/Plugins/SquirrelChatLog.nut b/MCServer/Plugins/SquirrelChatLog.nut
new file mode 100644
index 000000000..4ef0fd595
--- /dev/null
+++ b/MCServer/Plugins/SquirrelChatLog.nut
@@ -0,0 +1,13 @@
+class SquirrelChatLog extends Plugin
+{
+ function Initialize()
+ {
+ this.AddHook(Hook.Chat);
+ return true;
+ }
+
+ function OnChat(Message, Player)
+ {
+ ::print(Player.GetName() + ": " + Message);
+ }
+}
diff --git a/MCServer/Plugins/sTick/main.lua b/MCServer/Plugins/sTick/main.lua
new file mode 100644
index 000000000..16ac7167f
--- /dev/null
+++ b/MCServer/Plugins/sTick/main.lua
@@ -0,0 +1,20 @@
+
+-- Global variables
+PLUGIN = {} -- Reference to own plugin object
+
+
+
+
+
+function Initialize( Plugin )
+ PLUGIN = Plugin
+
+ Plugin:SetName( "sTick" )
+ Plugin:SetVersion( 8 )
+
+ PluginManager = cRoot:Get():GetPluginManager()
+ PluginManager:AddHook( Plugin, cPluginManager.E_PLUGIN_BLOCK_PLACE )
+
+ LOG( "Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion() )
+ return true
+end \ No newline at end of file
diff --git a/MCServer/Plugins/sTick/onblockplace.lua b/MCServer/Plugins/sTick/onblockplace.lua
new file mode 100644
index 000000000..0216b580e
--- /dev/null
+++ b/MCServer/Plugins/sTick/onblockplace.lua
@@ -0,0 +1,18 @@
+function OnBlockPlace( Block, Player )
+
+ -- dont check if the direction is in the air
+ if Block.m_Direction == -1 then
+ return false
+ end
+
+ if (Block.m_ItemType ~= 280) then -- not a Stick of Ticking
+ return false
+ end
+
+ LOG("Setting next block tick to {" .. Block.m_PosX .. ", " .. Block.m_PosY .. ", " .. Block.m_PosZ .. "}")
+
+ Player:GetWorld():SetNextBlockTick(Block.m_PosX, Block.m_PosY, Block.m_PosZ);
+
+ return true
+
+end \ No newline at end of file
diff --git a/MCServer/banned.example.ini b/MCServer/banned.example.ini
new file mode 100644
index 000000000..efe5f51b6
--- /dev/null
+++ b/MCServer/banned.example.ini
@@ -0,0 +1,3 @@
+[Banned]
+;PlayerName=1
+
diff --git a/MCServer/crafting.txt b/MCServer/crafting.txt
new file mode 100644
index 000000000..abadeeaa3
--- /dev/null
+++ b/MCServer/crafting.txt
@@ -0,0 +1,357 @@
+
+# This file describes the crafting recipes that MCServer knows.
+# The syntax is as follows:
+# <Line> = <Recipe>#<Comment>
+# <Recipe> = <Result> = <Ingredient1> | <Ingredient2> | ... | <IngredientN>
+# <IngredientN> = <ItemID>, <X1> : <Y1>, <X2> : <Y2>, ..., <Xn> : <Yn>
+# <ItemID> = <ItemType> [^<DamageValue>]
+# <Xn>, <Yn> = "1" .. "3", or "*" for any value. "*:*" can be replaced by a single "*".
+# <Result> = <ItemType> [^<DamageValue>] [, <Count>]
+#
+# The Xn, Yn coordinates are a reference to the crafting grid:
+# 1:1 | 2:1 | 3:1
+# 1:2 | 2:2 | 3:2
+# 1:3 | 2:3 | 3:3
+#
+# <ItemType> can be either a number, or an item name (checked against items.ini)
+#
+# ^<DamageValue> is optional, if not present, any damage value is matched for ingredients and zero is produced for the result
+#
+# Ingredients with an asterisk for a coord will not match already matched crafting grid items. This enables simplifying some of the recipes,
+# e. g. hoe: "Iron, 2:1, *:1"
+# -- this means "one iron at 2:1, and another one at either 1:1 or 3:1"
+#
+# To require multiple items of the same type in a slot, specify the slot number several times:
+# "Iron, 1:1, 2:2, 2:2"
+# -- this means "take one iron from slot 1:1 and two irons from slot 2:2"
+# Note that asterisked items cannot require multiple items in a single slot.
+#
+# Note that due to technical problems, it is NOT advised to use asterisked ingredients in crossing directions, such as "*:1, "2:*".
+# The parser may be unable to match such a recipe to the crafting grid!
+#
+# Whitespace is optional. Use it reasonably. Please do NOT use Tabs in the middle of lines!
+
+
+
+
+
+#******************************************************#
+# Basic Crafts
+#
+
+# Need to list each of the four log types, otherwise all logs would get converted into apple planks (^0)
+ApplePlanks, 4 = AppleLog, *
+ConiferPlanks, 4 = ConiferLog, *
+BirchPlanks, 4 = BirchLog, *
+JunglePlanks, 4 = JungleLog, *
+Stick, 4 = Planks, 2:2, 2:3
+Torch, 4 = Stick, 1:2 | Coal, 1:1
+Workbench = Planks, 1:1, 1:2, 2:1, 2:2
+Chest = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
+Furnace = Cobblestone, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
+
+
+
+
+
+#******************************************************#
+# Blocks
+#
+IronBlock = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
+GoldBlock = GoldIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
+DiamondBlock = Diamond, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
+LapisBlock = LapisLazuli, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
+Glowstone = GlowstoneDust, 1:1, 1:2, 2:1, 2:2
+Wool = String, 1:1, 1:2, 2:1, 2:2
+TNT = Gunpowder, 1:1, 3:1, 2:2, 1:3, 3:3 | Sand, 2:1, 1:2, 3:2, 2:3
+
+# Slabs:
+StoneSlab, 6 = Stone, 1:1, 2:1, 3:1
+SandstoneSlab, 6 = Sandstone, 1:1, 2:1, 3:1
+WoodSlab, 6 = Planks, 1:1, 2:1, 3:1
+CobblestoneSlab, 6 = Cobblestone, 1:1, 2:1, 3:1
+BrickSlab, 6 = BrickBlock, 1:1, 2:1, 3:1
+StonebrickSlab, 6 = StoneBrick, 1:1, 2:1, 3:1
+
+# Stairs:
+WoodStairs, 4 = Planks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
+WoodStairs, 4 = Planks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
+cobblestoneStairs, 4 = Cobblestone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
+cobblestoneStairs, 4 = Cobblestone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
+BrickStairs, 4 = BrickBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
+BrickStairs, 4 = BrickBlock, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
+SandstoneStairs, 4 = Sandstone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
+SandstoneStairs, 4 = Sandstone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
+NetherBrickStairs, 4 = NetherBrick, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
+NetherBrickStairs, 4 = NetherBrick, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
+
+SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
+ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
+BrickBlock = Brick, 1:1, 1:2, 2:1, 2:2
+StoneBrick, 4 = Stone, 1:1, 1:2, 2:1, 2:2
+BookShelf = Planks, 1:1, 2:1, 3:1, 1:3, 2:3, 3:3 | Book, 1:2, 2:2, 3:2
+Sandstone, 4 = Sand, 1:1, 1:2, 2:1, 2:2
+SmoothSandstone,4= Sandstone, 1:1, 1:2, 2:1, 2:2
+OrnamentSandstone= SandstoneSlab, 1:1, 1:2
+JackOLantern = Pumpkin, 1:1 | Torch, 1:2
+
+
+
+
+
+#******************************************************#
+# Tools
+#
+
+# Axes:
+WoodenAxe = Stick, 2:2, 2:3 | Planks, 2:1, *:1, *:2
+StoneAxe = Stick, 2:2, 2:3 | Cobblestone, 2:1, *:1, *:2
+GoldenAxe = Stick, 2:2, 2:3 | GoldIngot, 2:1, *:1, *:2
+IronAxe = Stick, 2:2, 2:3 | IronIngot, 2:1, *:1, *:2
+DiamondAxe = Stick, 2:2, 2:3 | Diamond, 2:1, *:1, *:2
+
+# Pickaxes:
+WoodenPickaxe = Stick, 2:2, 2:3 | Planks, 1:1, 2:1, 3:1
+StonePickaxe = Stick, 2:2, 2:3 | Cobblestone, 1:1, 2:1, 3:1
+GoldenPickaxe = Stick, 2:2, 2:3 | GoldIngot, 1:1, 2:1, 3:1
+IronPickaxe = Stick, 2:2, 2:3 | IronIngot, 1:1, 2:1, 3:1
+DiamondPickaxe = Stick, 2:2, 2:3 | Diamond, 1:1, 2:1, 3:1
+
+# Shovels:
+WoodenShovel = Stick, 2:2, 2:3 | Planks, 2:1
+StoneShovel = Stick, 2:2, 2:3 | Cobblestone, 2:1
+GoldenShovel = Stick, 2:2, 2:3 | GoldIngot, 2:1
+IronShovel = Stick, 2:2, 2:3 | IronIngot, 2:1
+DiamondShovel = Stick, 2:2, 2:3 | Diamond, 2:1
+
+# Hoes:
+WoodenHoe = Stick, 2:2, 2:3 | Planks, 2:1, *:1
+StoneHoe = Stick, 2:2, 2:3 | Cobblestone, 2:1, *:1
+GoldenHoe = Stick, 2:2, 2:3 | GoldIngot, 2:1, *:1
+IronHoe = Stick, 2:2, 2:3 | IronIngot, 2:1, *:1
+DiamondHoe = Stick, 2:2, 2:3 | Diamond, 2:1, *:1
+
+Lighter = IronIngot, 1:1 | Flint, 2:2
+Lighter = IronIngot, 2:1 | Flint, 1:2
+Bucket = IronIngot, 1:1, 2:2, 3:1
+Compass = IronIngot, 2:1, 1:2, 3:2, 2:3 | RedstoneDust, 2:2
+Map = Paper, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Compass, 2:2
+Watch = GoldIngot, 2:1, 1:2, 3:2, 2:3 | RedstoneDust, 2:2
+FishingRod = Stick, 1:3, 2:2, 3:1 | String, 3:2, 3:3
+FishingRod = Stick, 3:3, 2:2, 1:1 | String, 1:2, 1:3
+Shears = IronIngot, 1:1, 2:2
+Shears = IronIngot, 2:1, 1:2
+FireCharge = BlazePowder, * | Coal, * | Gunpowder, *
+
+
+
+
+
+#******************************************************#
+# Weapons
+#
+WoodenSword = Stick, 2:3 | Planks, 2:1, 2:2
+StoneSword = Stick, 2:3 | Cobblestone, 2:1, 2:2
+GoldenSword = Stick, 2:3 | GoldIngot, 2:1, 2:2
+IronSword = Stick, 2:3 | IronIngot, 2:1, 2:2
+DiamondSword = Stick, 2:3 | Diamond, 2:1, 2:2
+Bow = Stick, 2:1, 1:2, 2:3 | String, 3:1, 3:2, 3:3
+Bow = Stick, 2:1, 3:2, 2:3 | String, 1:1, 1:2, 1:3
+Arrow, 4 = Flint, 1:1 | Stick, 1:2 | Feather, 1:3
+
+
+
+
+
+
+#******************************************************#
+# Armor
+#
+
+# Helmets:
+LeatherHelmet = Leather, 1:1, 2:1, 3:1, 1:2, 3:2
+ChainmailHelmet = Fire, 1:1, 2:1, 3:1, 1:2, 3:2
+GoldenHelmet = GoldIngot, 1:1, 2:1, 3:1, 1:2, 3:2
+IronHelmet = IronIngot, 1:1, 2:1, 3:1, 1:2, 3:2
+DiamondHelmet = Diamond, 1:1, 2:1, 3:1, 1:2, 3:2
+
+# Chestplates:
+LeatherChestplate = Leather, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
+ChainmailChestplate = Fire, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
+GoldenChestplate = GoldIngot, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
+IronChestplate = IronIngot, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
+DiamondChestplate = Diamond, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 2:3, 3:3
+
+# Leggins:
+LeatherPants = Leather, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
+ChainmailPants = Fire, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
+GoldenPants = GoldIngot, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
+IronPants = IronIngot, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
+DiamondPants = Diamond, 1:1, 2:1, 3:1, 1:2, 3:2, 1:3, 3:3
+
+# Boots:
+LeatherBoots = Leather, 1:1, 3:1, 1:2, 3:2
+ChainmailBoots = Fire, 1:1, 3:1, 1:2, 3:2
+GoldenBoots = GoldIngot, 1:1, 3:1, 1:2, 3:2
+IronBoots = IronIngot, 1:1, 3:1, 1:2, 3:2
+DiamondBoots = Diamond, 1:1, 3:1, 1:2, 3:2
+
+
+
+
+
+#******************************************************#
+# Transportation
+#
+Minecart = IronIngot, 1:1, 3:1, 1:2, 2:2, 3:2
+PoweredMinecart = Minecart, * | Furnace, *
+StorageMinecart = Minecart, * | Chest, *
+Rails, 16 = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | Stick, 2:2
+PoweredRail, 6 = GoldIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | Stick, 2:2 | RedstoneDust, 2:3
+DetectorRail, 6 = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 3:3 | StonePlate, 2:2 | RedstoneDust, 2:3
+Boat = Planks, 1:1, 3:1, 1:2, 2:2, 3:2
+
+
+
+
+
+#******************************************************#
+# Mechanisms
+#
+WoodenDoor = Planks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
+IronDoor = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
+TrapDoor, 2 = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
+WoodPlate = Planks, 1:1, 2:1
+StonePlate = Stone, 1:1, 2:1
+Button = Stone, 1:1, 1:2
+RedstoneTorchOn = Stick, 1:2 | RedstoneDust, 1:1
+Lever = Cobblestone, 1:2 | Stick, 1:1
+NoteBlock = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | RedstoneDust, 2:2
+Jukebox = Planks, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Diamond, 2:2
+Dispenser = Cobblestone, 1:1, 1:2, 1:3, 2:1, 3:1, 3:2, 3:3 | RedstoneDust, 2:3 | Bow, 2:2
+Repeater = Stone, 1:2, 2:2, 3:2 | RedstoneTorchOn, 1:1, 3:1 | RedstoneDust, 2:1
+Piston = Planks, 1:1, 2:1, 3:1 | RedstoneDust, 2:2 | Cobblestone, 1:2, 3:2, 1:3, 2:3, 3:3
+StickyPiston = Piston, * | SlimeBall, *
+RedstoneLamp = RedstoneDust, 2:1, 1:2, 3:2, 2:3 | Glowstone, 2:2
+
+
+
+
+
+#******************************************************#
+# Food
+#
+Bowl = Planks, 1:1, 2:2, 3:1
+MushroomStew = Bowl, * | BrownMushroom, * | RedMushroom, *
+Bread = Wheat, 1:1, 2:1, 3:1
+Sugar = Sugarcane, *
+Cake = MilkBucket, 1:1, 2:1, 3:1 | Sugar, 1:2, 3:2 | Egg, 2:2 | Wheat, 1:3, 2:3, 3:3
+Cookie = Wheat, *, * | CocoaBeans, *
+GoldenApple = RedApple, 2:2 | GoldNugget, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3
+Melon = MelonSlice, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
+MelonSeeds = MelonSlice, *
+PumpkinSeeds, 4 = Pumpkin, *
+
+
+
+
+
+#******************************************************#
+# Miscellaneous
+#
+
+# Minerals:
+IronIngot, 9 = IronBlock, *
+GoldIngot, 9 = GoldBlock, *
+Diamond, 9 = DiamondBlock, *
+LapisLazuli, 9 = LapisBlock, *
+
+Painting = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Wool, 2:2
+Sign = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2 | Stick, 2:3
+Ladder, 3 = Stick, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 3:3
+GlassPane, 16 = Glass, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
+IronBars, 16 = IronIngot, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
+Paper, 3 = Sugarcane, 1:1, 2:1, 3:1
+Book = Paper, 1:1, 1:2, 1:3
+Fence, 2 = Stick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
+NetherBrickFence, 6 = NetherBrick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
+FenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | Planks, 2:1, 2:2
+Bed = Planks, 1:2, 2:2, 3:2 | Wool, 1:1, 2:1, 3:1
+GoldIngot = GoldNugget, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
+EyeOfEnder = EnderPearl, * | BlazePowder, *
+
+
+
+
+
+#******************************************************#
+# Dyes
+#
+
+WhiteDye, 3 = Bone, *
+RedDye, 2 = Rose, *
+YellowDye, 2 = Flower, *
+
+# Color mixing, duals:
+OrangeDye, 2 = YellowDye, * | RedDye, *
+CyanDye, 2 = GreenDye, * | BlueDye, *
+PurpleDye, 2 = RedDye, * | BlueDye, *
+GrayDye, 2 = BlackDye, * | WhiteDye, *
+LtBlueDye, 2 = BlueDye, * | WhiteDye, *
+PinkDye, 2 = RedDye, * | WhiteDye, *
+LimeDye, 2 = GreenDye, * | WhiteDye, *
+MagentaDye, 2 = PurpleDye, * | PinkDye, *
+LtGrayDye, 2 = GrayDye, * | WhiteDye, *
+
+# triplets:
+LtGrayDye, 3 = BlackDye, * | WhiteDye, *, *
+MagentaDye, 3 = BlueDye, * | PinkDye, * | RedDye, *
+
+# quads:
+MagentaDye, 4 = BlueDye, * | WhiteDye, * | RedDye, *, *
+
+
+
+
+
+#******************************************************#
+# Colored wool:
+#
+WhiteWool = Wool, * | BoneMeal, *
+OrangeWool = Wool, * | OrangeDye, *
+MagentaWool = Wool, * | MagentaDye, *
+LightBlueWool = Wool, * | LightBlueDye, *
+YellowWool = Wool, * | YellowDye, *
+LimeWool = Wool, * | LimeDye, *
+PinkWool = Wool, * | PinkDye, *
+GrayWool = Wool, * | GrayDye, *
+LightGrayWool = Wool, * | LightGrayDye, *
+CyanWool = Wool, * | CyanDye, *
+VioletWool = Wool, * | VioletDye, *
+BlueWool = Wool, * | BlueDye, *
+BrownWool = Wool, * | BrownDye, *
+GreenWool = Wool, * | GreenDye, *
+RedWool = Wool, * | RedDye, *
+BlackWool = Wool, * | BlackDye, *
+
+
+
+
+
+#******************************************************#
+# Enchantment & Brewing
+#
+GlassBottle, 3 = Glass, 1:1, 2:2, 3:1
+Cauldron = IronIngot, 1:1, 3:1, 1:2, 3:2, 1:3, 2:3, 3:3
+BrewingStand = Cobblestone, 1:2, 2:2, 3:2 | BlazeRod, 2:1
+BlazePowder, 2 = BlazeRod, *
+MagmaCream = SlimeBall, * | BlazePowder, *
+FermentedSpiderEye = SpiderEye, * | Sugar, * | BrownMushroom, *
+GlisteringMelon = MelonSlice, * | GoldNugget, *
+GoldNugget, 9 = GoldIngot, *
+EnchantmentTable = Obsidian, 1:3, 2:3, 3:3, 2:2 | Diamond, 1:2, 3:2 | Book, 2:1
+
+
+
+
+
diff --git a/MCServer/furnace.txt b/MCServer/furnace.txt
new file mode 100644
index 000000000..c8e3cd0c7
--- /dev/null
+++ b/MCServer/furnace.txt
@@ -0,0 +1,64 @@
+#**************************
+# Default Furnace Recipes #
+#*************************#
+#
+#
+#******************************************************#
+# Basic Notation Help
+#******************************************************#
+#
+# **** Item Definition ****
+# An Item is defined by an Item ID, an amount (and health)
+# The health is optional, and if not specified it's
+# assumed to be 0
+#
+# -Cactus Green:
+# 351 : 1 ( : 2 )
+# ItemID : Amount ( : Health )
+#
+#
+# **** Recipe and result ****
+#
+# 4:1@10000=1:1 -> Produces 1 smooth stone from
+# 1 cobblestone in 10 second
+#
+# 4 : 1 @ 10000 = 1 : 1
+# ItemID : Amount @ milliseconds = ItemID : Amount
+#
+# **** Burnable Materials / Fuel ****
+#
+# !17:1=15000 -> 1 Wood burns for 15000 milliseconds
+# (15 s)
+#
+# ! 17 : 1 = 15000
+# Fuel ItemID : Amount = milliseconds
+#
+#******************************************************#
+
+#--------------------------
+# Let's get cookin' :D
+
+4:1 @10000=1:1 #-> 1 Cobblestone -> 1 Rock
+15:1 @10000=265:1 #-> 1 Iron Ore -> 1 Iron Ingot
+14:1 @10000=266:1 #-> 1 Gold Ore -> 1 Gold Ingot
+12:1 @10000=20:1 #-> 1 Sand -> 1 Glass
+319:1@10000=320:1 #-> 1 Raw Pork -> 1 Cooked Pork
+337:1@10000=336:1 #-> 1 Clay -> 1 Clay Brick
+349:1@10000=350:1 #-> 1 Raw Fish -> 1 Cooked Fish
+17:1 @10000=263:1 #-> 1 Wood -> 1 Charcoal
+81:1 @10000=351:1:2 #-> 1 Cactus -> 1 Dye
+
+#--------------------------
+# Burn baby! Buuurn!
+
+!263:1 = 80000 #-> 1 Charcoal -> 80 sec
+!5:1 = 15000 #-> 1 Planks -> 15 sec
+!280:1 = 5000 #-> 1 Stick -> 5 sec
+!85:1 = 15000 #-> 1 Fence -> 15 sec
+!53:1 = 15000 #-> 1 Wooden Stairs -> 15 sec
+!58:1 = 15000 #-> 1 Crafting Table -> 15 sec
+!47:1 = 15000 #-> 1 Bookshelf -> 15 sec
+!54:1 = 15000 #-> 1 Chest -> 15 sec
+!84:1 = 15000 #-> 1 Jukebox -> 15 sec
+!327:1 = 1000000 #-> 1 Lava Bucket -> 1000 sec
+!17:1 = 15000 #-> 1 Wood -> 15 sec \ No newline at end of file
diff --git a/MCServer/groups.example.ini b/MCServer/groups.example.ini
new file mode 100644
index 000000000..7f061204b
--- /dev/null
+++ b/MCServer/groups.example.ini
@@ -0,0 +1,17 @@
+[Admins]
+Permissions=*
+Color=c
+
+[Mods]
+Color=5
+Inherits=Vips
+Permissions=core.time,core.item
+
+[Vips]
+Permissions=core.teleport
+Color=2
+Inherits=Default
+
+[Default]
+Permissions=core.build,core.help,core.playerlist,core.pluginlist,core.spawn
+Color=7 \ No newline at end of file
diff --git a/MCServer/groups.ini b/MCServer/groups.ini
new file mode 100644
index 000000000..7f061204b
--- /dev/null
+++ b/MCServer/groups.ini
@@ -0,0 +1,17 @@
+[Admins]
+Permissions=*
+Color=c
+
+[Mods]
+Color=5
+Inherits=Vips
+Permissions=core.time,core.item
+
+[Vips]
+Permissions=core.teleport
+Color=2
+Inherits=Default
+
+[Default]
+Permissions=core.build,core.help,core.playerlist,core.pluginlist,core.spawn
+Color=7 \ No newline at end of file
diff --git a/MCServer/items.ini b/MCServer/items.ini
new file mode 100644
index 000000000..5b9012521
--- /dev/null
+++ b/MCServer/items.ini
@@ -0,0 +1,471 @@
+[Items]
+rock=1
+stone=1
+grass=2
+dirt=3
+cobblestone=4
+cobble=4
+planks=5
+appleplanks=5:0
+oakplanks=5:0
+coniferplanks=5:1
+pineplanks=5:1
+spruceplanks=5:1
+darkplanks=5:1
+birchplanks=5:2
+lightplanks=5:2
+jungleplanks=5:3
+redplanks=5:3
+
+; Obsolete: do not use "wood", as its meaning is not clear - wiki uses log as wood, we use planks as wood.
+wood=5
+
+sapling=6
+applesapling=6:0
+oaksapling=6:0
+conifersapling=6:1
+pinesapling=6:1
+sprucesapling=6:1
+birchsapling=6:2
+junglesapling=6:3
+adminium=7
+bedrock=7
+water=8
+stillwater=9
+swater=9
+lava=10
+stilllava=11
+slava=11
+sand=12
+gravel=13
+goldore=14
+ironore=15
+coalore=16
+tree=17
+log=17
+applelog=17:0
+oaklog=17:0
+coniferlog=17:1
+pinelog=17:1
+sprucelog=17:1
+darklog=17:1
+birchlog=17:2
+whitelog=17:2
+junglelog=17:3
+leaves=18
+appleleaves=18:0
+oakleaves=18:0
+coniferleaves=18:1
+pineleaves=18:1
+spruceleaves=18:1
+birchleaves=18:2
+jungleleaves=18:3
+sponge=19
+glass=20
+lapisore=21
+lapisblock=22
+dispenser=23
+sandstone=24
+normalsandstone=24:0
+ornamentsandstone=24:1
+decorativesandstone=24:1
+smoothsandstone=24:2
+noteblock=25
+bedblock=26
+poweredrail=27
+detectorrail=28
+stickypiston=29
+cobweb=30
+tallgrass=31
+tallgrassone=31:1
+tallgrasstwo=31:2
+deadbush=32
+piston=33
+pistonextension=34
+pistonhead=34
+cloth=35
+wool=35
+whitewool=35:0
+orangewool=35:1
+magentawool=35:2
+lightbluewool=35:3
+yellowwool=35:4
+limewool=35:5
+lightgreenwool=35:5
+ltgreenwool=35:5
+pinkwool=35:6
+graywool=35:7
+greywool=35:7
+darkgraywool=35:7
+darkgreywool=35:7
+dkgraywool=35:7
+dkgreywool=35:7
+lightgraywool=35:8
+lightgreywool=35:8
+ltgraywool=35:8
+ltgreywool=35:8
+cyanwool=35:9
+purplewool=35:10
+violetwool=35:10
+bluewool=35:11
+darkbluewool=35:11
+brownwool=35:12
+greenwool=35:13
+darkgreenwool=35:13
+dkgreenwool=35:13
+redwool=35:14
+blackwool=35:15
+flower=37
+rose=38
+brownmushroom=39
+redmushroom=40
+gold=41
+goldblock=41
+iron=42
+ironblock=42
+doubleslab=43
+stonedoubleslab=43:0
+sandstonedoubleslab=43:1
+wooddoubleslab=43:2
+cobblestonedoubleslab=43:3
+brickdoubleslab=43:4
+stonebrickdoubleslab=43:5
+slab=44
+step=44
+stoneslab=44:0
+sandstoneslab=44:1
+woodslab=44:2
+cobblestoneslab=44:3
+brickslab=44:4
+stonebrickslab=44:5
+brickblock=45
+brickwall=45
+tnt=46
+bookshelf=47
+bookcase=47
+mossycobblestone=48
+mossy=48
+obsidian=49
+torch=50
+fire=51
+mobspawner=52
+woodstairs=53
+chest=54
+redstonedust=55
+redstonewire=55
+diamondore=56
+diamondblock=57
+workbench=58
+crop=59
+crops=59
+soil=60
+furnace=61
+litfurnace=62
+signblock=63
+wooddoorblock=64
+ladder=65
+rails=66
+rail=66
+track=66
+tracks=66
+cobblestonestairs=67
+stairs=67
+signblocktop=68
+wallsign=68
+lever=69
+rockplate=70
+stoneplate=70
+irondoorblock=71
+woodplate=72
+redstoneore=73
+redstoneorealt=74
+redstonetorchoff=75
+redstonetorchon=76
+button=77
+snow=78
+ice=79
+snowblock=80
+cactus=81
+clayblock=82
+reedblock=83
+jukebox=84
+fence=85
+pumpkin=86
+netherstone=87
+netherrack=87
+hellrock=87
+slowsand=88
+soulsand=88
+lightstone=89
+glowstone=89
+portal=90
+jackolantern=91
+jacko=91
+cakeblock=92
+lockedchest=95
+trapdoor=96
+silverfishblock=97
+stonebricks=98
+stonebrick=98
+mossystonebrick=98:1
+crackedstonebrick=98:2
+chiseledstonebrick=98:3
+hugebrownmushroom=99
+hugeredmushroom=100
+ironbars=101
+glasspane=102
+melon=103
+pumpkinstem=104
+melonstem=105
+vines=106
+fencegate=107
+brickstairs=108
+stonebrickstairs=109
+mycelium=110
+lilypad=111
+netherbrick=112
+netherbrickfence=113
+netherbrickstairs=114
+netherwartblock=115
+enchantmenttable=116
+brewingstandblock=117
+cauldronblock=118
+endportal=119
+endportalframe=120
+endstone=121
+dragonegg=122
+redstonelamp=123
+redstonelampoff=123
+redstonelampon=124
+woodendoubleslab=125
+woodenslab=126
+sandstonestairs=128
+ironshovel=256
+ironspade=256
+ironpickaxe=257
+ironpick=257
+ironaxe=258
+flintandsteel=259
+lighter=259
+apple=260
+redapple=260
+bow=261
+arrow=262
+coal=263
+charcoal=263:1
+diamond=264
+ironingot=265
+ironbar=265
+goldingot=266
+goldeningot=266
+goldbar=266
+goldenbar=266
+ironsword=267
+woodensword=268
+woodsword=268
+woodenshovel=269
+woodshovel=269
+woodenspade=269
+woodspade=269
+woodenpickaxe=270
+woodpickaxe=270
+woodenpick=270
+woodpick=270
+woodenaxe=271
+woodaxe=271
+stonesword=272
+stoneshovel=273
+stonespade=273
+stonepickaxe=274
+stonepick=274
+stoneaxe=275
+diamondsword=276
+diamondshovel=277
+diamondspade=277
+diamondpickaxe=278
+diamondpick=278
+diamondaxe=279
+stick=280
+bowl=281
+mushroomstew=282
+bowlwithsoup=282
+soupbowl=282
+soup=282
+goldensword=283
+goldsword=283
+goldenshovel=284
+goldshovel=284
+goldenspade=284
+goldspade=284
+goldenpickaxe=285
+goldpickaxe=285
+goldenpick=285
+goldpick=285
+goldenaxe=286
+goldaxe=286
+string=287
+feather=288
+gunpowder=289
+woodhoe=290
+woodenhoe=290
+stonehoe=291
+ironhoe=292
+diamondhoe=293
+goldhoe=294
+goldenhoe=294
+seeds=295
+wheat=296
+bread=297
+leatherhelmet=298
+leatherchestplate=299
+leatherpants=300
+leatherboots=301
+chainmailhelmet=302
+chainmailchestplate=303
+chainmailpants=304
+chainmailboots=305
+ironhelmet=306
+ironchestplate=307
+ironpants=308
+ironboots=309
+diamondhelmet=310
+diamondchestplate=311
+diamondpants=312
+diamondboots=313
+goldenhelmet=314
+goldhelmet=314
+goldenchestplate=315
+goldchestplate=315
+goldenpants=316
+goldpants=316
+goldenboots=317
+goldboots=317
+flint=318
+meat=319
+pork=319
+cookedmeat=320
+cookedpork=320
+painting=321
+paintings=321
+goldenapple=322
+goldapple=322
+sign=323
+wooddoor=324
+woodendoor=324
+bucket=325
+waterbucket=326
+lavabucket=327
+minecart=328
+saddle=329
+irondoor=330
+redstonedust=331
+snowball=332
+boat=333
+leather=334
+milkbucket=335
+brick=336
+clay=337
+reed=338
+sugarcane=338
+paper=339
+book=340
+slimeorb=341
+slimeball=341
+storageminecart=342
+poweredminecart=343
+egg=344
+compass=345
+fishingrod=346
+watch=347
+lightstonedust=348
+lightdust=348
+glowstonedust=348
+glowdust=348
+rawfish=349
+fish=349
+cookedfish=350
+dye=351
+inksac=351:0
+blackdye=351:0
+reddye=351:1
+rosered=351:1
+greendye=351:2
+cactusgreen=351:2
+cocoabeans=351:3
+browndye=351:3
+lapislazuli=351:4
+bluedye=351:4
+darkbluedye=351:4
+dkbluedye=351:4
+purpledye=351:5
+violetdye=351:5
+cyandye=351:6
+lightgreydye=351:7
+lightgraydye=351:7
+ltgreydye=351:7
+ltgraydye=351:7
+greydye=351:8
+graydye=351:8
+darkgreydye=351:8
+darkgraydye=351:8
+dkgreydye=351:8
+dkgraydye=351:8
+pinkdye=351:9
+limedye=351:10
+lightgreendye=351:10
+ltgreendye=351:10
+dandellionyellow=351:11
+yellowdye=351:11
+lightbluedye=351:12
+ltbluedye=351:12
+magentadye=351:13
+orangedye=351:14
+bonemeal=351:15
+whitedye=351:15
+bone=352
+sugar=353
+cake=354
+bed=355
+repeater=356
+diode=356
+cookie=357
+map=358
+shears=359
+melonslice=360
+pumpkinseeds=361
+melonseeds=362
+rawbeef=363
+steak=364
+rawchicken=365
+cookedchicken=366
+rottenflesh=367
+enderpearl=368
+blazerod=369
+ghasttear=370
+goldnugget=371
+netherwart=372
+potion=373
+glassbottle=374
+spidereye=375
+fermentedspidereye=376
+blazepowder=377
+magmacream=378
+brewingstand=379
+cauldron=380
+eyeofender=381
+glisteringmelon=382
+spawnegg=383
+bottleoenchanting=384
+firecharge=385
+goldrecord=2256
+greenrecord=2257
+blocksrecord=2258
+chirprecord=2259
+farrecord=2260
+mallrecord=2261
+mellohirecord=2262
+stalrecord=2263
+stradrecord=2264
+wardrecord=2265
+11record=2266
+
diff --git a/MCServer/monsters.ini b/MCServer/monsters.ini
new file mode 100644
index 000000000..6634c5bef
--- /dev/null
+++ b/MCServer/monsters.ini
@@ -0,0 +1,111 @@
+[Spider]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=1.0
+SightDistance=25.0
+MaxHealth=10
+
+[Chicken]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=1.0
+SightDistance=25.0
+MaxHealth=4
+
+[Cow]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=1.0
+SightDistance=25.0
+MaxHealth=10
+
+[Pig]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=1.0
+SightDistance=25.0
+MaxHealth=10
+
+[Sheep]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=1.0
+SightDistance=25.0
+MaxHealth=8
+
+[Squid]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=1.0
+SightDistance=25.0
+MaxHealth=10
+
+[Enderman]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=4.0
+SightDistance=25.0
+MaxHealth=40
+
+[Zombiepigman]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=5.0
+SightDistance=25.0
+MaxHealth=20
+
+[Cavespider]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=2.0
+SightDistance=25.0
+MaxHealth=12
+
+[Creeper]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=0.0
+SightDistance=25.0
+MaxHealth=20
+
+[Ghast]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=0.0
+SightDistance=25.0
+MaxHealth=10
+
+[Silverfish]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=1.0
+SightDistance=25.0
+MaxHealth=8
+
+[Skeleton]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=4.0
+SightDistance=25.0
+MaxHealth=20
+
+[Slime]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=10.0
+SightDistance=25.0
+MaxHealth=32
+
+[Spider]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=2.0
+SightDistance=25.0
+MaxHealth=16
+
+[Zombie]
+AttackRange=5.0
+AttackRate=1
+AttackDamage=4.0
+SightDistance=25.0
+MaxHealth=20 \ No newline at end of file
diff --git a/MCServer/settings.example.ini b/MCServer/settings.example.ini
new file mode 100644
index 000000000..bfb16c7e6
--- /dev/null
+++ b/MCServer/settings.example.ini
@@ -0,0 +1,31 @@
+[Server]
+Port=25565
+MaxPlayers=42
+Description=MCServer - Slightly more custom!
+
+[Worlds]
+DefaultWorld=world
+;World=world_sexy
+
+[Plugins]
+NewPlugin=Core
+NewPlugin=ChatLog
+
+[HelpPlugin]
+ShowPluginNames=1
+
+[Physics]
+Water=0
+
+[Redstone]
+SimulateRedstone=0
+
+[Monsters]
+AnimalsOn=0
+AnimalSpawnInterval=10
+Types=Spider,Chicken,Cow,Pig,Sheep,Squid,Enderman,Zombiepigman,Cavespider,Creeper,Ghast,Silverfish,Skeleton,Slime,Spider,Zombie
+
+[Authentication]
+Server=session.minecraft.net
+Address=/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%
+Authenticate=0
diff --git a/MCServer/settings.ini b/MCServer/settings.ini
new file mode 100644
index 000000000..ab1519021
--- /dev/null
+++ b/MCServer/settings.ini
@@ -0,0 +1,37 @@
+[Server]
+Port=25565
+MaxPlayers=10000
+Description=MCServer - Slightly more custom!
+
+[Worlds]
+;World=world_sexy
+DefaultWorld=world
+
+[Plugins]
+;NewPlugin=Protect
+;NewPlugin=MagicCarpet
+;NewPlugin=ChatLog
+;NewPlugin=BlockInfo
+NewPlugin=CuboidPlus
+NewPlugin=Core
+NewPlugin=ChunkWorx
+
+[HelpPlugin]
+ShowPluginNames=1
+
+[Physics]
+Water=0
+
+[Redstone]
+SimulateRedstone=0
+
+[Monsters]
+AnimalsOn=0
+AnimalSpawnInterval=10
+Types=Spider,Chicken,Cow,Pig,Sheep,Squid,Enderman,Zombiepigman,Cavespider,Creeper,Ghast,Silverfish,Skeleton,Slime,Spider,Zombie
+
+[Authentication]
+Server=session.minecraft.net
+Address=/game/checkserver.jsp?user=%USERNAME%&serverId=%SERVERID%
+Authenticate=0
+
diff --git a/MCServer/terrain.ini b/MCServer/terrain.ini
new file mode 100644
index 000000000..a917223f9
--- /dev/null
+++ b/MCServer/terrain.ini
@@ -0,0 +1,8 @@
+[Terrain]
+HeightFreq1=0.100000
+HeightFreq2=1.000000
+HeightFreq3=2.000000
+HeightAmp1=1.000000
+HeightAmp2=0.500000
+HeightAmp3=0.500000
+
diff --git a/MCServer/users.example.ini b/MCServer/users.example.ini
new file mode 100644
index 000000000..fae7030f1
--- /dev/null
+++ b/MCServer/users.example.ini
@@ -0,0 +1,8 @@
+[SomeAdmin]
+Groups=Admins
+
+[FancyModerator]
+Groups=Moderators
+
+[ImportantPerson]
+Groups=Vips \ No newline at end of file
diff --git a/MCServer/users.ini b/MCServer/users.ini
new file mode 100644
index 000000000..21a52760f
--- /dev/null
+++ b/MCServer/users.ini
@@ -0,0 +1,20 @@
+[FakeTruth]
+Groups=Admins
+
+[Duralex]
+Groups=Admins
+
+[Luthrandel]
+Groups=Admins
+
+[cruisecho]
+Groups=Admins
+
+[Kwen]
+Groups=Admins
+
+[aloe_vera]
+Groups=Admins
+
+[xoft]
+Groups=Admins
diff --git a/MCServer/webadmin.example.ini b/MCServer/webadmin.example.ini
new file mode 100644
index 000000000..6ecbf7513
--- /dev/null
+++ b/MCServer/webadmin.example.ini
@@ -0,0 +1,6 @@
+[WebAdmin]
+Enabled=1
+Port=8080
+
+[User:admin]
+Password=admin \ No newline at end of file
diff --git a/MCServer/webadmin.ini b/MCServer/webadmin.ini
new file mode 100644
index 000000000..7384f0bde
--- /dev/null
+++ b/MCServer/webadmin.ini
@@ -0,0 +1,6 @@
+[WebAdmin]
+Enabled=1
+Port=8081
+
+[User:admin]
+Password=admin \ No newline at end of file
diff --git a/MCServer/webadmin/template.html b/MCServer/webadmin/template.html
new file mode 100644
index 000000000..a607c3f53
--- /dev/null
+++ b/MCServer/webadmin/template.html
@@ -0,0 +1,376 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="icon" href="data:application/octet-stream;base64,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">
+<title>{TITLE}</title>
+
+<style type="text/css" media="screen">
+
+ /* reset CSS */
+
+ html, body, div, span, applet, object, iframe,
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+ a, abbr, acronym, address, big, cite, code,
+ del, dfn, em, font, img, ins, kbd, q, s, samp,
+ small, strike, strong, sub, sup, tt, var,
+ b, u, i, center,
+ dl, dt, dd, ol, ul, li,
+ fieldset, form, label, legend,
+ table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+ }
+ body {
+ line-height: 1;
+ }
+ ol, ul {
+ list-style: none;
+ }
+ blockquote, q {
+ quotes: none;
+ }
+
+ /* remember to define focus styles! */
+ :focus {
+ outline: 0;
+ }
+
+ /* remove textarea resize at Safari */
+ textarea {
+ resize: none;
+ }
+
+ /* remember to highlight inserts somehow! */
+ ins {
+ text-decoration: none;
+ }
+ del {
+ text-decoration: line-through;
+ }
+
+ /* tables still need 'cellspacing="0"' in the markup */
+ table {
+ border-collapse: collapse;
+ border-spacing: 0;
+ }
+
+
+ /*
+ Origional from http://www.perspectived.com/
+ Modified by Ben Phelps
+ Made for FakeTruth - MCServer
+ */
+
+ /* Basic ---------------------------------------- */
+
+ .clear { clear: both; }
+
+ body {
+ background: white;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ color: #646464;
+ text-align: center;
+ }
+
+ #wrapper {
+ text-align: left;
+ width: 930px;
+ margin: 0 auto;
+ }
+
+ /* Logo ---------------------------------------- */
+
+ h1 {
+ margin: 15px 0 10px 5px;
+ width: 180px;
+ height: 36px;
+ background: url(data:image/png;base64,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) no-repeat left top;
+ }
+
+ h1 a {
+ display: block;
+ width: 225px;
+ height: 28px;
+ }
+
+ h1 span { display: none; }
+
+ a {
+ color: #646464;
+ }
+
+ /* Container ---------------------------------------- */
+
+ #containerHolder {
+ background: #eee;
+ padding: 5px;
+ }
+
+
+ #container {
+ background: #fff url(data:image/gif;base64,R0lGODlhtAABAIAAAN3d3f///yH5BAAAAAAALAAAAAC0AAEAAAIMjI+py+0Po5y0WgYKADs%3D) repeat-y left top;
+ border: 1px solid #ddd;
+ width: 918px;
+
+ }
+
+ #connectHolder {
+ background: #eee;
+ padding: 5px;
+ margin-bottom:8px;
+ }
+
+
+ #connect {
+ border: 1px solid #ddd;
+ background-color: #fff;
+ padding:5px;
+ width: 908px;
+ }
+
+ .pics {
+ height: 375px;
+ width: 600px;
+ }
+
+ .pics img {
+ padding: 5px;
+ border: 1px solid #ddd;
+ background-color: #eee;
+ width: 600px;
+ height: 375px;
+ margin-left: 15px;
+ }
+
+ /* Login -------------------------------------- */
+
+ #loginLogo {
+ margin: 0 auto;
+ margin-top:100px;
+ width: 180px;
+ height: 36px;
+ background-image: url(data:image/png;base64,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);
+ }
+
+ #loginHolder {
+ background: #eee;
+ padding: 5px;
+ width: 310px;
+ margin: 0 auto;
+ height: 90px;
+ margin-top:20px;
+ }
+
+ #login {
+ padding:10px;
+ width: 288px;
+ height: 68px;
+ border: 1px solid #ddd;
+ background:#fff;
+ text-align: left;
+ }
+
+
+ /* Sidebar ---------------------------------------- */
+
+ #sidebar {
+ width: 179px;
+ float: left;
+ }
+
+ #sidebar .sideNav { width: 179px; }
+
+ #sidebar .sideNav li { border-bottom: 1px solid #ddd; width: 179px; }
+
+ #sidebar .sideNav li a {
+ display: block;
+ color: #646464;
+ background: #f6f6f6;
+ text-decoration: none;
+ height: 29px;
+ line-height: 29px;
+ padding: 0 19px;
+ width: 141px;
+ }
+
+ #sidebar .sideNav li a:hover { background: #fdfcf6; }
+
+ #sidebar .sideNav li a.active, #sidebar .sideNav li a.active:hover {
+ background: #f0f7fa;
+ color: #c66653;
+ }
+
+ /* Breadcrumb ---------------------------------------- */
+
+ h2 {
+ width: 718px;
+ float: right;
+ color: #646464;
+ font-size: 16px;
+ line-height: 16px;
+ font-weight: bold;
+ margin: 20px 0 0 0;
+ padding: 0 0 10px 0;
+ border-bottom: 1px solid #ddd;
+ }
+
+ h2 a {
+ color: #646464;
+ text-decoration: none;
+ }
+
+ h2 a.active { color: #c66653; }
+
+ h2 a:hover { text-decoration: underline; }
+
+ /* Content ---------------------------------------- */
+
+ #main {
+ width: 700px;
+ float: right;
+ padding: 0 19px 0 0;
+ }
+
+ #main p {
+
+ padding: 10px;
+
+ }
+
+ h3 {
+ font-size: 14px;
+ line-height: 14px;
+ font-weight: bold;
+ color: #5494af;
+ padding: 0 0 0 10px;
+ margin: 20px 0 10px;
+ }
+
+ h4 {
+ padding: 0 0 0 10px;
+ margin: 20px 0 10px;
+ }
+
+ #main ul {
+ padding: 0 0 0 10px;
+ list-style-type: circle;
+ list-style-position: inside;
+ }
+
+ #main table {
+ border-top: 1px solid #ddd;
+ width: 700px;
+ }
+
+ #main table tr th {
+ text-align: left;
+ background: #f6f6f6;
+ padding: 0px 20px;
+ height: 20px;
+ line-height: 20px;
+ border-bottom: 1px solid #ddd;
+ }
+
+ #main table tr td {
+ background: #f6f6f6;
+ padding: 0px 20px;
+ height: 29px;
+ line-height: 29px;
+ border-bottom: 1px solid #ddd;
+ }
+
+ #main table tr.odd td {
+ background: #fbfbfb;
+ }
+
+ #main table tr:hover td { background: #fdfcf6; }
+
+ #main table .action {
+ text-align: right;
+ padding: 0 20px 0 10px;
+ }
+
+ #main table tr .action a { margin: 0 0 0 10px; text-decoration: none; color: #9b9b9b; }
+ #main table tr:hover .action .edit { color: #c5a059; }
+ #main table tr:hover .action .delete { color: #a02b2b; }
+ #main table tr:hover .action .view { color: #55a34a; }
+
+ #main table tr:hover .action a:hover { text-decoration: underline; }
+
+ fieldset {
+ border: 1px solid #ddd;
+ padding: 19px;
+ margin: 0 0 20px 0;
+ background: #fbfbfb;
+ }
+
+ form p { margin: 0 0 14px 0; float: left; width: 100%; }
+
+ label {
+ display: block;
+ width: 100%;
+ margin: 0 0 7px 0;
+ line-height: 12px;
+ }
+
+ /* Footer ---------------------------------------- */
+
+ #footer {
+ margin: 10px 0 30px 0;
+ font-size: 11px;
+ line-height: 11px;
+ color: #9B9B9B;
+ padding: 0 0 0 5px;
+ }
+
+ #footer a { color: #9B9B9B; }
+
+ #footer a:hover { text-decoration: none; }
+</style>
+
+</head>
+
+<body>
+ <div id="wrapper">
+ <!-- h1 tag stays for the logo, you can use the a tag for linking the index page -->
+ <h1><a href="./"><span>{TITLE}</span></a></h1>
+
+ <div id="containerHolder">
+ <div id="container">
+ <div id="sidebar">
+ <ul class="sideNav">
+ {MENU}
+ </ul>
+ <!-- // .sideNav -->
+ </div>
+ <!-- // #sidebar -->
+
+ <!-- h2 stays for breadcrumbs -->
+ <h2>Welcome {USERNAME}</h2>
+
+ <div id="main">
+ <h3>{PLUGIN_NAME}</h3>
+
+ {CONTENT}
+
+ </div>
+ <!-- // #main -->
+
+ <div class="clear"></div>
+ </div>
+ <!-- // #container -->
+ </div>
+ <!-- // #containerHolder -->
+
+ <p id="footer">Memory Usage: {MEM}Mb; Current chunk count: {NUMCHUNKS} </p>
+ </div>
+ <!-- // #wrapper -->
+</body>
+</html>
diff --git a/MCServer/whitelist.example.ini b/MCServer/whitelist.example.ini
new file mode 100644
index 000000000..eb884dcda
--- /dev/null
+++ b/MCServer/whitelist.example.ini
@@ -0,0 +1,6 @@
+[WhiteListSettings]
+WhiteListOn=0
+
+[WhiteList]
+;PlayerName=1
+