summaryrefslogtreecommitdiffstats
path: root/MCServer
diff options
context:
space:
mode:
Diffstat (limited to 'MCServer')
-rw-r--r--MCServer/Plugins/APIDump/APIDesc.lua104
-rw-r--r--MCServer/Plugins/APIDump/Classes/Projectiles.lua83
-rw-r--r--MCServer/Plugins/APIDump/Hooks/OnServerPing.lua50
m---------MCServer/Plugins/ChatLog0
-rw-r--r--MCServer/Plugins/ChatLog/plugin.lua31
m---------MCServer/Plugins/ChunkWorx0
-rw-r--r--MCServer/Plugins/ChunkWorx/ChunkWorx.deproj9
-rw-r--r--MCServer/Plugins/ChunkWorx/chunkworx_main.lua128
-rw-r--r--MCServer/Plugins/ChunkWorx/chunkworx_web.lua274
m---------MCServer/Plugins/Core0
-rw-r--r--MCServer/Plugins/Debuggers/Debuggers.lua19
m---------MCServer/Plugins/Handy0
-rw-r--r--MCServer/Plugins/Handy/handy.lua28
-rw-r--r--MCServer/Plugins/Handy/handy_functions.lua216
-rw-r--r--MCServer/Plugins/InfoDump.lua431
m---------MCServer/Plugins/MagicCarpet0
-rw-r--r--MCServer/Plugins/MagicCarpet/objects.lua97
-rw-r--r--MCServer/Plugins/MagicCarpet/plugin.lua81
m---------MCServer/Plugins/ProtectionAreas0
-rw-r--r--MCServer/webadmin/(original).html8
-rw-r--r--MCServer/webadmin/files/guest.html2
-rw-r--r--MCServer/webadmin/files/header.pngbin0 -> 221 bytes
-rw-r--r--MCServer/webadmin/files/home.gifbin0 -> 1026 bytes
-rw-r--r--MCServer/webadmin/files/loading.gifbin0 -> 7364 bytes
-rw-r--r--MCServer/webadmin/files/log_out.pngbin0 -> 995 bytes
-rw-r--r--MCServer/webadmin/files/login.css219
-rw-r--r--MCServer/webadmin/files/login.gifbin0 -> 586 bytes
-rw-r--r--MCServer/webadmin/files/logo_login.pngbin0 -> 18057 bytes
-rw-r--r--MCServer/webadmin/files/pmfolder.gifbin0 -> 995 bytes
-rw-r--r--MCServer/webadmin/files/style.css547
-rw-r--r--MCServer/webadmin/files/sub_pmfolder.gifbin0 -> 1022 bytes
-rw-r--r--MCServer/webadmin/files/tcat.pngbin0 -> 183 bytes
-rw-r--r--MCServer/webadmin/files/thead.pngbin0 -> 132 bytes
-rw-r--r--MCServer/webadmin/login_template.html78
-rw-r--r--MCServer/webadmin/template.html261
-rw-r--r--MCServer/webadmin/template.lua143
-rw-r--r--MCServer/webadmin/template_orig.lua137
37 files changed, 1437 insertions, 1509 deletions
diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua
index e6ee4ca10..9b87781a6 100644
--- a/MCServer/Plugins/APIDump/APIDesc.lua
+++ b/MCServer/Plugins/APIDump/APIDesc.lua
@@ -524,22 +524,29 @@ end
Functions =
{
GenerateOfflineUUID = { Params = "Username", Return = "string", Notes = "(STATIC) Generates an UUID based on the player name provided. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. Returns a 32-char UUID (no dashes)." },
+ GetClientBrand = { Params = "", Return = "string", Notes = "Returns the brand that the client has sent in their MC|Brand plugin message." },
GetIPString = { Params = "", Return = "string", Notes = "Returns the IP address of the connection, as a string. Only the address part is returned, without the port number." },
GetLocale = { Params = "", Return = "Locale", Notes = "Returns the locale string that the client sends as part of the protocol handshake. Can be used to provide localized strings." },
GetPing = { Params = "", Return = "number", Notes = "Returns the ping time, in ms" },
GetPlayer = { Params = "", Return = "{{cPlayer|cPlayer}}", Notes = "Returns the player object connected to this client. Note that this may be nil, for example if the player object is not yet spawned." },
+ GetProtocolVersion = { Params = "", Return = "number", Notes = "Returns the protocol version number of the protocol that the client is talking. Returns zero if the protocol version is not (yet) known." },
GetUniqueID = { Params = "", Return = "number", Notes = "Returns the UniqueID of the client used to identify the client in the server" },
GetUUID = { Params = "", Return = "string", Notes = "Returns the authentication-based UUID of the client. This UUID should be used to identify the player when persisting any player-related data. Returns a 32-char UUID (no dashes)" },
GetUsername = { Params = "", Return = "string", Notes = "Returns the username that the client has provided" },
GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" },
+ GetRequestedViewDistance = { Params = "", Return = "number", Notes = "Returns the view distance that the player request, not the used view distance." },
HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." },
IsUUIDOnline = { Params = "UUID", Return = "bool", Notes = "(STATIC) Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false."},
Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" },
SendPluginMessage = { Params = "Channel, Message", Return = "", Notes = "Sends the plugin message on the specified channel." },
+ SetClientBrand = { Params = "ClientBrand", Return = "", Notes = "Sets the value of the client's brand. Normally this value is received from the client by a MC|Brand plugin message, this function lets plugins overwrite the value." },
SetLocale = { Params = "Locale", Return = "", Notes = "Sets the locale that MCServer keeps on record. Initially the locale is initialized in protocol handshake, this function allows plugins to override the stored value (but only server-side and only until the user disconnects)." },
SetUsername = { Params = "Name", Return = "", Notes = "Sets the username" },
SetViewDistance = { Params = "ViewDistance", Return = "", Notes = "Sets the viewdistance (number of chunks loaded for the player in each direction)" },
SendBlockChange = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta", Return = "", Notes = "Sends a BlockChange packet to the client. This can be used to create fake blocks only for that player." },
+ SendEntityAnimation = { Params = "{{cEntity|Entity}}, AnimationNumber", Return = "", Notes = "Sends the specified animation of the specified entity to the client. The AnimationNumber is protocol-specific." },
+ SendSoundEffect = { Params = "SoundName, X, Y, Z, Volume, Pitch", Return = "", Notes = "Sends a sound effect request to the client. The sound is played at the specified coords, with the specified volume (a float, 1.0 is full volume, can be more) and pitch (0-255, 63 is 100%)" },
+ SendTimeUpdate = { Params = "WorldAge, TimeOfDay, DoDaylightCycle", Return = "", Notes = "Sends the specified time update to the client. WorldAge is the total age of the world, in ticks. TimeOfDay is the current day's time, in ticks (0 - 24000). DoDaylightCycle is a bool that specifies whether the client should automatically move the sun (true) or keep it in the same place (false)." },
},
Constants =
{
@@ -555,9 +562,9 @@ end
and commands suggested on click. The chat message can be sent by the regular chat-sending functions,
{{cPlayer}}:SendMessage(), {{cWorld}}:BroadcastChat() and {{cRoot}}:BroadcastChat().</p>
<p>
- Note that most of the functions in this class are so-called modifiers - they modify the object and
- then return the object itself, so that they can be chained one after another. See the Chaining
- example below for details.</p>
+ Note that most of the functions in this class are so-called chaining modifiers - they modify the
+ object and then return the object itself, so that they can be chained one after another. See the
+ Chaining example below for details.</p>
<p>
Each part of the composite chat message takes a "Style" parameter, this is a string that describes
the formatting. It uses the following strings, concatenated together:
@@ -581,14 +588,17 @@ end
{ Params = "Text", Return = "", Notes = "Creates a chat message containing the specified text, parsed by the ParseText() function. This allows easy migration from old chat messages." },
},
AddRunCommandPart = { Params = "Text, Command, [Style]", Return = "self", Notes = "Adds a text which, when clicked, runs the specified command. Chaining." },
+ AddShowAchievementPart = { Params = "PlayerName, AchievementName, [Style]", Return = "", Notes = "Adds a text that represents the 'Achievement get' message." },
AddSuggestCommandPart = { Params = "Text, Command, [Style]", Return = "self", Notes = "Adds a text which, when clicked, puts the specified command into the player's chat input area. Chaining." },
AddTextPart = { Params = "Text, [Style]", Return = "self", Notes = "Adds a regular text. Chaining." },
AddUrlPart = { Params = "Text, Url, [Style]", Return = "self", Notes = "Adds a text which, when clicked, opens up a browser at the specified URL. Chaining." },
Clear = { Params = "", Return = "", Notes = "Removes all parts from this object" },
+ CreateJsonString = { Params = "[AddPrefixes]", Return = "string", Notes = "Returns the entire object serialized into JSON, as it would be sent to a client. AddPrefixes specifies whether the chat prefixes should be prepended to the message, true by default." },
ExtractText = { Params = "", Return = "string", Notes = "Returns the text from the parts that comprises the human-readable data. Used for older protocols that don't support composite chat and for console-logging." },
+ GetAdditionalMessageTypeData = { Params = "", Return = "string", Notes = "Returns the AdditionalData associated with the message, such as the sender's name for mtPrivateMessage" },
GetMessageType = { Params = "", Return = "MessageType", Notes = "Returns the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.)" },
ParseText = { Params = "Text", Return = "self", Notes = "Adds text, while recognizing http and https URLs and old-style formatting codes (\"@2\"). Chaining." },
- SetMessageType = { Params = "MessageType", Return = "self", Notes = "Sets the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.) Chaining." },
+ SetMessageType = { Params = "MessageType, AdditionalData", Return = "self", Notes = "Sets the MessageType (mtXXX constant) that is associated with this message. Also sets the additional data (string) associated with the message, which is specific for the message type - such as the sender's name for mtPrivateMessage. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.). Chaining." },
UnderlineUrls = { Params = "", Return = "self", Notes = "Makes all URL parts contained in the message underlined. Doesn't affect parts added in the future. Chaining." },
},
@@ -605,7 +615,7 @@ function OnPlayerJoined(a_Player)
-- Send an example composite chat message to the player:
a_Player:SendMessage(cCompositeChat()
:AddTextPart("Hello, ")
- :AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2") -- Colored underlined link
+ :AddUrlPart(a_Player:GetName(), "http://www.mc-server.org", "u@2") -- Colored underlined link
:AddSuggestCommandPart(", and welcome.", "/help", "u") -- Underlined suggest-command
:AddRunCommandPart(" SetDay", "/time set 0") -- Regular text that will execute command when clicked
:SetMessageType(mtJoin) -- It is a join-message
@@ -777,7 +787,9 @@ end</pre>
AddSpeedX = { Params = "AddX", Return = "", Notes = "Adds the specified amount of speed in the X axis direction." },
AddSpeedY = { Params = "AddY", Return = "", Notes = "Adds the specified amount of speed in the Y axis direction." },
AddSpeedZ = { Params = "AddZ", Return = "", Notes = "Adds the specified amount of speed in the Z axis direction." },
+ ArmorCoversAgainst = { Params = "{{cEntity|AttackerEntity}}, DamageType, RawDamage", Return = "number", Notes = "Returns the points out of a_RawDamage that the currently equipped armor would cover." },
Destroy = { Params = "", Return = "", Notes = "Schedules the entity to be destroyed" },
+ GetAirLevel = { Params = "", Return = "number", Notes = "Returns the air level (number of ticks of air left). Note, this function is only updated with mobs or players." },
GetArmorCoverAgainst = { Params = "AttackerEntity, DamageType, RawDamage", Return = "number", Notes = "Returns the number of hitpoints out of RawDamage that the currently equipped armor would cover. See {{TakeDamageInfo}} for more information on attack damage." },
GetChunkX = { Params = "", Return = "number", Notes = "Returns the X-coord of the chunk in which the entity is placed" },
GetChunkZ = { Params = "", Return = "number", Notes = "Returns the Z-coord of the chunk in which the entity is placed" },
@@ -793,6 +805,7 @@ end</pre>
GetHeadYaw = { Params = "", Return = "number", Notes = "Returns the pitch of the entity's head (FIXME: Rename to GetHeadPitch() )." },
GetHealth = { Params = "", Return = "number", Notes = "Returns the current health of the entity." },
GetHeight = { Params = "", Return = "number", Notes = "Returns the height (Y size) of the entity" },
+ GetInvulnerableTicks = { Params = "", Return = "number", Notes = "Returns the number of ticks that this entity will be invulnerable for. This is used for after-hit recovery - the entities are invulnerable for half a second after being hit." },
GetKnockbackAmountAgainst = { Params = "ReceiverEntity", Return = "number", Notes = "Returns the amount of knockback that the currently equipped items would cause when attacking the ReceiverEntity." },
GetLookVector = { Params = "", Return = "{{Vector3f}}", Notes = "Returns the vector that defines the direction in which the entity is looking" },
GetMass = { Params = "", Return = "number", Notes = "Returns the mass of the entity. Currently unused." },
@@ -810,23 +823,29 @@ end</pre>
GetSpeedX = { Params = "", Return = "number", Notes = "Returns the X-part of the speed vector" },
GetSpeedY = { Params = "", Return = "number", Notes = "Returns the Y-part of the speed vector" },
GetSpeedZ = { Params = "", Return = "number", Notes = "Returns the Z-part of the speed vector" },
+ GetTicksAlive = { Params = "", Return = "number", Notes = "Returns the number of ticks that this entity has been alive for." },
GetUniqueID = { Params = "", Return = "number", Notes = "Returns the ID that uniquely identifies the entity within the running server. Note that this ID is not persisted to the data files." },
GetWidth = { Params = "", Return = "number", Notes = "Returns the width (X and Z size) of the entity." },
GetWorld = { Params = "", Return = "{{cWorld}}", Notes = "Returns the world where the entity resides" },
GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. Measured in degrees, values range from -180 to +180. 0 means ZP, 90 means XM, -180 means ZM, -90 means XP." },
+ HandleSpeedFromAttachee = { Params = "ForwardAmount, SidewaysAmount", Return = "", Notes = "Updates the entity's speed based on the attachee exerting the specified force forward and sideways. Used for entities being driven by other entities attached to them - usually players driving minecarts and boats." },
Heal = { Params = "Hitpoints", Return = "", Notes = "Heals the specified number of hitpoints. Hitpoints is expected to be a positive number." },
IsA = { Params = "ClassName", Return = "bool", Notes = "Returns true if the entity class is a descendant of the specified class name, or the specified class itself" },
IsBoat = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cBoat|boat}}." },
IsCrouched = { Params = "", Return = "bool", Notes = "Returns true if the entity is crouched. Always false for entities that don't support crouching." },
IsDestroyed = { Params = "", Return = "bool", Notes = "Returns true if the entity has been destroyed and is awaiting removal from the internal structures." },
+ IsEnderCrystal = { Params = "", Return = "bool", Notes = "Returns true if the entity is an ender crystal." },
IsExpOrb = { Params = "", Return = "bool", Notes = "Returns true if the entity represents an experience orb" },
IsFallingBlock = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cFallingBlock}} entity." },
+ IsFireproof = { Params = "", Return = "bool", Notes = "Returns true if the entity takes no damage from being on fire." },
IsFloater = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a fishing rod floater" },
IsInvisible = { Params = "", Return = "bool", Notes = "Returns true if the entity is invisible" },
+ IsItemFrame = { Params = "", Return = "bool", Notes = "Returns true if the entity is an item frame." },
IsMinecart = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cMinecart|minecart}}" },
IsMob = { Params = "", Return = "bool", Notes = "Returns true if the entity represents any {{cMonster|mob}}." },
IsOnFire = { Params = "", Return = "bool", Notes = "Returns true if the entity is on fire" },
IsPainting = { Params = "", Return = "bool", Notes = "Returns if this entity is a painting." },
+ IsPawn = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cPawn}} descendant." },
IsPickup = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cPickup|pickup}}." },
IsPlayer = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cPlayer|player}}" },
IsProjectile = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cProjectileEntity}} descendant." },
@@ -836,12 +855,19 @@ end</pre>
IsSubmerged = { Params = "", Return = "bool", Notes = "Returns true if the mob or player is submerged in water (head is in a water block). Note, this function is only updated with mobs or players." },
IsSwimming = { Params = "", Return = "bool", Notes = "Returns true if the mob or player is swimming in water (feet are in a water block). Note, this function is only updated with mobs or players." },
IsTNT = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cTNTEntity|TNT entity}}" },
+ Killed = { Params = "{{cEntity|Victim}}", Return = "", Notes = "This entity has killed another entity (the Victim). For players, adds the scoreboard statistics about the kill." },
KilledBy = { Notes = "FIXME: Remove this from API" },
- GetAirLevel = { Params = "", Return = "number", Notes = "Returns the air level (number of ticks of air left). Note, this function is only updated with mobs or players." },
+ MoveToWorld =
+ {
+ { Params = "{{cWorld|World}}, [ShouldSendRespawn]", Return = "bool", Notes = "Removes the entity from this world and starts moving it to the specified world. Note that to avoid deadlocks, the move is asynchronous - the entity is moved into a queue and will be moved from that queue into the destination world at some (unpredictable) time in the future. ShouldSendRespawn is used only for players, it specifies whether the player should be sent a Repawn packet upon leaving the world (The client handles respawns only between different dimensions)." },
+ { Params = "WorldName, [ShouldSendRespawn]", Return = "bool", Notes = "Removes the entity from this world and starts moving it to the specified world. Note that to avoid deadlocks, the move is asynchronous - the entity is moved into a queue and will be moved from that queue into the destination world at some (unpredictable) time in the future. ShouldSendRespawn is used only for players, it specifies whether the player should be sent a Repawn packet upon leaving the world (The client handles respawns only between different dimensions)." },
+ },
SetGravity = { Params = "Gravity", Return = "", Notes = "Sets the number that is used as the gravity for physics simulation. 1G (9.78) by default." },
SetHeadYaw = { Params = "HeadPitch", Return = "", Notes = "Sets the head pitch (FIXME: Rename to SetHeadPitch() )." },
SetHealth = { Params = "Hitpoints", Return = "", Notes = "Sets the entity's health to the specified amount of hitpoints. Doesn't broadcast any hurt animation. Doesn't kill the entity if health drops below zero. Use the TakeDamage() function instead for taking damage." },
SetHeight = { Params = "", Return = "", Notes = "FIXME: Remove this from API" },
+ SetInvulnerableTicks = { Params = "NumTicks", Return = "", Notes = "Sets the amount of ticks for which the entity will not receive any damage from other entities." },
+ SetIsFireproof = { Params = "IsFireproof", Return = "", Notes = "Sets whether the entity receives damage from being on fire." },
SetMass = { Params = "Mass", Return = "", Notes = "Sets the mass of the entity. Currently unused." },
SetMaxHealth = { Params = "MaxHitpoints", Return = "", Notes = "Sets the maximum hitpoints of the entity. If current health is above MaxHitpoints, it is capped to MaxHitpoints." },
SetPitch = { Params = "number", Return = "", Notes = "Sets the pitch (nose-down rotation) of the entity" },
@@ -856,7 +882,7 @@ end</pre>
SetPosZ = { Params = "number", Return = "", Notes = "Sets the Z-coord of the entity's pivot" },
SetRoll = { Params = "number", Return = "", Notes = "Sets the roll (sideways rotation) of the entity. Currently unused." },
SetRot = { Params = "{{Vector3f|Rotation}}", Return = "", Notes = "Sets the entire rotation vector (Yaw, Pitch, Roll)" },
- SetYawFromSpeed = { Params = "", Return = "", Notes = "Sets the entity's yaw to match its current speed (entity looking forwards as it moves). (FIXME: Rename to SetYawFromSpeed)" },
+ SetYawFromSpeed = { Params = "", Return = "", Notes = "Sets the entity's yaw to match its current speed (entity looking forwards as it moves)." },
SetSpeed =
{
{ Params = "SpeedX, SpeedY, SpeedZ", Return = "", Notes = "Sets the current speed of the entity" },
@@ -882,18 +908,20 @@ end</pre>
Constants =
{
etBoat = { Notes = "The entity is a {{cBoat}}" },
+ etEnderCrystal = { Notes = "" },
etEntity = { Notes = "No further specialization available" },
etExpOrb = { Notes = "The entity is a {{cExpOrb}}" },
etFallingBlock = { Notes = "The entity is a {{cFallingBlock}}" },
etFloater = { Notes = "The entity is a fishing rod floater" },
+ etItemFrame = { Notes = "" },
+ etMinecart = { Notes = "The entity is a {{cMinecart}} descendant" },
etMob = { Notes = "The entity is a {{cMonster}} descendant" },
etMonster = { Notes = "The entity is a {{cMonster}} descendant" },
- etMinecart = { Notes = "The entity is a {{cMinecart}} descendant" },
- etPlayer = { Notes = "The entity is a {{cPlayer}}" },
+ etPainting = { Notes = "The entity is a {{cPainting}}" },
etPickup = { Notes = "The entity is a {{cPickup}}" },
+ etPlayer = { Notes = "The entity is a {{cPlayer}}" },
etProjectile = { Notes = "The entity is a {{cProjectileEntity}} descendant" },
etTNT = { Notes = "The entity is a {{cTNTEntity}}" },
- etPainting = { Notes = "The entity is a {{cPainting}}" },
},
ConstantGroups =
{
@@ -1043,6 +1071,7 @@ ValueName0=SomeOtherValue
GetValueSetB = { Params = "KeyName, ValueName, Default", Return = "bool", Notes = "Returns the value of the specified name under the specified key, as a bool. If the value doesn't exist, creates it with the specified default." },
GetValueSetF = { Params = "KeyName, ValueName, Default", Return = "number", Notes = "Returns the value of the specified name under the specified key, as a floating-point number. If the value doesn't exist, creates it with the specified default." },
GetValueSetI = { Params = "KeyName, ValueName, Default", Return = "number", Notes = "Returns the value of the specified name under the specified key, as an integer. If the value doesn't exist, creates it with the specified default." },
+ HasValue = { Params = "KeyName, ValueName", Return = "bool", Notes = "Returns true if the specified value is present." },
ReadFile = { Params = "FileName, [AllowExampleFallback]", Return = "bool", Notes = "Reads the values from the specified file. Previous in-memory contents are lost. If the file cannot be opened, and AllowExample is true, another file, \"filename.example.ini\", is loaded and then saved as \"filename.ini\". Returns true if successful, false if not." },
SetValue =
{
@@ -1740,6 +1769,7 @@ a_Player:OpenWindow(Window);
GetItem = { Params = "", Return = "{{cItem|cItem}}", Notes = "Returns the item represented by this pickup" },
IsCollected = { Params = "", Return = "bool", Notes = "Returns true if this pickup has already been collected (is waiting to be destroyed)" },
IsPlayerCreated = { Params = "", Return = "bool", Notes = "Returns true if the pickup was created by a player" },
+ SetAge = { Params = "AgeTicks", Return = "", Notes = "Sets the pickup's age, in ticks." },
},
Inherits = "cEntity",
}, -- cPickup
@@ -1764,8 +1794,8 @@ a_Player:OpenWindow(Window);
ForceSetSpeed = { Params = "{{Vector3d|Direction}}", Notes = "Forces the player to move to the given direction." },
GetClientHandle = { Params = "", Return = "{{cClientHandle}}", Notes = "Returns the client handle representing the player's connection. May be nil (AI players)." },
GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player's messages (based on their rank). Prefix player messages with this code." },
- GetPlayerListName = { Return = "string", Notes = "Returns the name that is used in the playerlist." },
GetCurrentXp = { Params = "", Return = "number", Notes = "Returns the current amount of XP" },
+ GetCustomName = { Params = "", Return = "string", Notes = "Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string." },
GetEffectiveGameMode = { Params = "", Return = "{{Globals#GameMode|GameMode}}", Notes = "(OBSOLETE) Returns the current resolved game mode of the player. If the player is set to inherit the world's gamemode, returns that instead. See also GetGameMode() and IsGameModeXXX() functions. Note that this function is the same as GetGameMode(), use that function instead." },
GetEquippedItem = { Params = "", Return = "{{cItem}}", Notes = "Returns the item that the player is currently holding; empty item if holding nothing." },
GetEyeHeight = { Return = "number", Notes = "Returns the height of the player's eyes, in absolute coords" },
@@ -1780,18 +1810,24 @@ a_Player:OpenWindow(Window);
GetGameMode = { Return = "{{Globals#GameMode|GameMode}}", Notes = "Returns the player's gamemode. The player may have their gamemode unassigned, in which case they inherit the gamemode from the current {{cWorld|world}}.<br /> <b>NOTE:</b> Instead of comparing the value returned by this function to the gmXXX constants, use the IsGameModeXXX() functions. These functions handle the gamemode inheritance automatically."},
GetIP = { Return = "string", Notes = "Returns the IP address of the player, if available. Returns an empty string if there's no IP to report."},
GetInventory = { Return = "{{cInventory|Inventory}}", Notes = "Returns the player's inventory"},
+ GetLastBedPos = { Params = "", Return = "{{Vector3i}}", Notes = "Returns the position of the last bed the player has slept in, or the world's spawn if no such position was recorded." },
GetMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's current maximum speed, relative to the game default speed. Takes into account the sprinting / flying status." },
GetName = { Return = "string", Notes = "Returns the player's name" },
GetNormalMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's maximum walking speed, relative to the game default speed. Defaults to 1, but plugins may modify it for faster or slower walking." },
+ GetPermissions = { Params = "", Return = "array-table of strings", Notes = "Returns the list of all permissions that the player has assigned to them through their rank." },
+ GetPlayerListName = { Return = "string", Notes = "Returns the name that is used in the playerlist." },
GetResolvedPermissions = { Return = "array-table of string", Notes = "Returns all the player's permissions, as a table. The permissions are stored in the array part of the table, beginning with index 1." },
GetSprintingMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's maximum sprinting speed, relative to the game default speed. Defaults to 1.3, but plugins may modify it for faster or slower sprinting." },
GetStance = { Return = "number", Notes = "Returns the player's stance (Y-pos of player's eyes)" },
+ GetTeam = { Params = "", Return = "{{cTeam}}", Notes = "Returns the team that the player belongs to, or nil if none." },
GetThrowSpeed = { Params = "SpeedCoeff", Return = "{{Vector3d}}", Notes = "Returns the speed vector for an object thrown with the specified speed coeff. Basically returns the normalized look vector multiplied by the coeff, with a slight random variation." },
GetThrowStartPos = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the position where the projectiles should start when thrown by this player." },
+ GetUUID = { Params = "", Return = "string", Notes = "Returns the (short) UUID that the player is using. Could be empty string for players that don't have a Mojang account assigned to them (in the future, bots for example)." },
GetWindow = { Params = "", Return = "{{cWindow}}", Notes = "Returns the currently open UI window. If the player doesn't have any UI window open, returns the inventory window." },
GetXpLevel = { Params = "", Return = "number", Notes = "Returns the current XP level (based on current XP amount)." },
GetXpLifetimeTotal = { Params = "", Return = "number", Notes = "Returns the amount of XP that has been accumulated throughout the player's lifetime." },
GetXpPercentage = { Params = "", Return = "number", Notes = "Returns the percentage of the experience bar - the amount of XP towards the next XP level. Between 0 and 1." },
+ HasCustomName = { Params = "", Return = "bool", Notes = "Returns true if the player has a custom name." },
HasPermission = { Params = "PermissionString", Return = "bool", Notes = "Returns true if the player has the specified permission" },
Heal = { Params = "HitPoints", Return = "", Notes = "Heals the player by the specified amount of HPs. Only positive amounts are expected. Sends a health update to the client." },
IsEating = { Params = "", Return = "bool", Notes = "Returns true if the player is currently eating the item in their hand." },
@@ -1799,7 +1835,9 @@ a_Player:OpenWindow(Window);
IsFlying = { Return = "bool", Notes = "Returns true if the player is flying." },
IsGameModeAdventure = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmAdventure gamemode, or has their gamemode unset and the world is a gmAdventure world." },
IsGameModeCreative = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmCreative gamemode, or has their gamemode unset and the world is a gmCreative world." },
+ IsGameModeSpectator = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmSpectator gamemode, or has their gamemode unset and the world is a gmSpectator world." },
IsGameModeSurvival = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmSurvival gamemode, or has their gamemode unset and the world is a gmSurvival world." },
+ IsInBed = { Params = "", Return = "bool", Notes = "Returns true if the player is currently lying in a bed." },
IsOnGround = { Params = "", Return = "bool", Notes = "Returns true if the player is on ground (not falling, not jumping, not flying)" },
IsSatiated = { Params = "", Return = "bool", Notes = "Returns true if the player is satiated (cannot eat)." },
IsVisible = { Params = "", Return = "bool", Notes = "Returns true if the player is visible to other players" },
@@ -1807,6 +1845,7 @@ a_Player:OpenWindow(Window);
MoveTo = { Params = "{{Vector3d|NewPosition}}", Return = "Tries to move the player into the specified position." },
MoveToWorld = { Params = "WorldName", Return = "bool", Return = "Moves the player to the specified world. Returns true if successful." },
OpenWindow = { Params = "{{cWindow|Window}}", Return = "", Notes = "Opens the specified UI window for the player." },
+ PermissionMatches = { Params = "Permission, Template", Return = "bool", Notes = "(STATIC) Returns true if the specified permission matches the specified template. The template may contain wildcards." },
Respawn = { Params = "", Return = "", Notes = "Restores the health, extinguishes fire, makes visible and sends the Respawn packet." },
SendMessage = { Params = "Message", Return = "", Notes = "Sends the specified message to the player." },
SendMessageFailure = { Params = "Message", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For a command that failed to run because of insufficient permissions, etc." },
@@ -1815,12 +1854,12 @@ a_Player:OpenWindow(Window);
SendMessagePrivateMsg = { Params = "Message, SenderName", Return = "", Notes = "Prepends Light Blue [MSG: *SenderName*] / prepends SenderName and colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For private messaging." },
SendMessageSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Success notification." },
SendMessageWarning = { Params = "Message, Sender", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Denotes that something concerning, such as plugin reload, is about to happen." },
- HasCustomName = { Params = "", Return = "bool", Notes = "Returns true if the player has a custom name." },
- GetCustomName = { Params = "", Return = "string", Notes = "Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string." },
- SetCustomName = { Params = "string", Return = "", Notes = "Sets the custom name of this player. If you want to disable the custom name, simply set an empty string. The custom name will be used in the tab-list, in the player nametag and in the tab-completion." },
+ SendRotation = { Params = "YawDegrees, PitchDegrees", Return = "", Notes = "Sends the specified rotation to the player, forcing them to look that way" },
+ SetBedPos = { Params = "{{Vector3i|Position}}", Return = "", Notes = "Sets the internal representation of the last bed position the player has slept in. The player will respawn at this position if they die." },
SetCanFly = { Params = "CanFly", Notes = "Sets if the player can fly or not." },
SetCrouch = { Params = "IsCrouched", Return = "", Notes = "Sets the crouch state, broadcasts the change to other players." },
SetCurrentExperience = { Params = "XPAmount", Return = "", Notes = "Sets the current amount of experience (and indirectly, the XP level)." },
+ SetCustomName = { Params = "string", Return = "", Notes = "Sets the custom name of this player. If you want to disable the custom name, simply set an empty string. The custom name will be used in the tab-list, in the player nametag and in the tab-completion." },
SetFlying = { Params = "IsFlying", Notes = "Sets if the player is flying or not." },
SetFlyingMaxSpeed = { Params = "FlyingMaxSpeed", Return = "", Notes = "Sets the flying maximum speed, relative to the game default speed. The default value is 1. Sends the updated speed to the client." },
SetFoodExhaustionLevel = { Params = "ExhaustionLevel", Return = "", Notes = "Sets the food exhaustion to the specified level." },
@@ -1834,7 +1873,11 @@ a_Player:OpenWindow(Window);
SetNormalMaxSpeed = { Params = "NormalMaxSpeed", Return = "", Notes = "Sets the normal (walking) maximum speed, relative to the game default speed. The default value is 1. Sends the updated speed to the client, if appropriate." },
SetSprint = { Params = "IsSprinting", Return = "", Notes = "Sets whether the player is sprinting or not." },
SetSprintingMaxSpeed = { Params = "SprintingMaxSpeed", Return = "", Notes = "Sets the sprinting maximum speed, relative to the game default speed. The default value is 1.3. Sends the updated speed to the client, if appropriate." },
+ SetTeam = { Params = "{{cTeam|Team}}", Return = "", Notes = "Moves the player to the specified team." },
SetVisible = { Params = "IsVisible", Return = "", Notes = "Sets the player visibility to other players" },
+ TossEquippedItem = { Params = "[Amount]", Return = "", Notes = "Tosses the item that the player has selected in their hotbar. Amount defaults to 1." },
+ TossHeldItem = { Params = "[Amount]", Return = "", Notes = "Tosses the item held by the cursor, then the player is in a UI window. Amount defaults to 1." },
+ TossPickup = { Params = "{{cItem|Item}}", Return = "", Notes = "Tosses a pickup newly created from the specified item." },
XpForLevel = { Params = "XPLevel", Return = "number", Notes = "(STATIC) Returns the total amount of XP needed for the specified XP level. Inverse of CalcLevelFromXp()." },
},
Constants =
@@ -1984,6 +2027,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
HOOK_PLAYER_USING_ITEM = { Notes = "Called when the player is about to right-click with a usable item in their hand." },
HOOK_POST_CRAFTING = { Notes = "Called after a valid recipe has been chosen for the current contents of the crafting grid. Plugins may modify the recipe." },
HOOK_PRE_CRAFTING = { Notes = "Called before a recipe is searched for the current contents of the crafting grid. Plugins may provide a recipe and cancel the built-in search." },
+ HOOK_SERVER_PING = { Notes = "Called when a client pings the server from the server list. Plugins may change the favicon, server description, players online and maximum players values." },
HOOK_SPAWNED_ENTITY = { Notes = "Called after an entity is spawned in a {{cWorld|world}}. The entity is already part of the world." },
HOOK_SPAWNED_MONSTER = { Notes = "Called after a mob is spawned in a {{cWorld|world}}. The mob is already part of the world." },
HOOK_SPAWNING_ENTITY = { Notes = "Called just before an entity is spawned in a {{cWorld|world}}." },
@@ -2033,8 +2077,10 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
AddGroupToRank = { Params = "GroupName, RankName", Return = "bool", Notes = "Adds the specified group to the specified rank. Returns true on success, false on failure - if the group name or the rank name is not found." },
AddPermissionToGroup = { Params = "Permission, GroupName", Return = "bool", Notes = "Adds the specified permission to the specified group. Returns true on success, false on failure - if the group name is not found." },
AddRank = { Params = "RankName, MsgPrefix, MsgSuffix, MsgNameColorCode", Return = "", Notes = "Adds a new rank of the specified name and with the specified message visuals. Logs an info message and does nothing if the rank already exists." },
+ ClearPlayerRanks = { Params = "", Return = "", Notes = "Removes all player ranks from the database. Note that this doesn't change the cPlayer instances for the already connected players, you need to update all the instances manually." },
GetAllGroups = { Params = "", Return = "array-table of groups' names", Notes = "Returns an array-table containing the names of all the groups that are known to the manager." },
GetAllPermissions = { Params = "", Return = "array-table of permissions", Notes = "Returns an array-table containing all the permissions that are known to the manager." },
+ GetAllPlayerUUIDs = { Params = "", Return = "array-table of uuids", Notes = "Returns the short uuids of all players stored in the rank DB, sorted by the players' names (case insensitive)." },
GetAllRanks = { Params = "", Return = "array-table of ranks' names", Notes = "Returns an array-table containing the names of all the ranks that are known to the manager." },
GetDefaultRank = { Params = "", Return = "string", Notes = "Returns the name of the default rank. " },
GetGroupPermissions = { Params = "GroupName", Return = "array-table of permissions", Notes = "Returns an array-table containing the permissions that the specified group contains." },
@@ -2042,6 +2088,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
GetPlayerMsgVisuals = { Params = "PlayerUUID", Return = "MsgPrefix, MsgSuffix, MsgNameColorCode", Notes = "Returns the message visuals assigned to the player. If the player is not explicitly assigned a rank, the default rank's visuals are returned. If there is an error, no value is returned at all." },
GetPlayerPermissions = { Params = "PlayerUUID", Return = "array-table of permissions", Notes = "Returns the permissions that the specified player is assigned through their rank. Returns the default rank's permissions if the player has no explicit rank assigned to them. Returns an empty array on error." },
GetPlayerRankName = { Params = "PlayerUUID", Return = "RankName", Notes = "Returns the name of the rank that is assigned to the specified player. An empty string (NOT the default rank) is returned if the player has no rank assigned to them." },
+ GetPlayerName = { Params = "PlayerUUID", Return = "PlayerName", Notes = "Returns the last name that the specified player has, for a player in the ranks database. An empty string is returned if the player isn't in the database." },
GetRankGroups = { Params = "RankName", Return = "array-table of groups' names", Notes = "Returns an array-table of the names of all the groups that are assigned to the specified rank. Returns an empty table if there is no such rank." },
GetRankPermissions = { Params = "RankName", Return = "array-table of permissions", Notes = "Returns an array-table of all the permissions that are assigned to the specified rank through its groups. Returns an empty table if there is no such rank." },
GetRankVisuals = { Params = "RankName", Return = "MsgPrefix, MsgSuffix, MsgNameColorCode", Notes = "Returns the message visuals for the specified rank. Returns no value if the specified rank does not exist." },
@@ -2076,14 +2123,22 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
]],
Functions =
{
- BroadcastChat = { Params = "Message", Return = "", Notes = "Broadcasts a message to every player in the server. No formatting is done by the server." },
- BroadcastChatFailure = { Params = "Message", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For a command that failed to run because of insufficient permissions, etc." },
- BroadcastChatFatal = { Params = "Message", Return = "", Notes = "Prepends Red [FATAL] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For a plugin that crashed, or similar." },
- BroadcastChatInfo = { Params = "Message", Return = "", Notes = "Prepends Yellow [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For informational messages, such as command usage." },
- BroadcastChatSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For success messages." },
- BroadcastChatWarning = { Params = "Message", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For concerning events, such as plugin reload etc." },
- CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil." },
+ BroadcastChat =
+ {
+ { Params = "MessageText, MessageType", Return = "", Notes = "Broadcasts a message to all players, with its message type set to MessageType (default: mtCustom)." },
+ { Params = "{{cCompositeChat|CompositeChat}}", Return = "", Notes = "Broadcasts a {{cCompositeChat|composite chat message} to all players." },
+ },
+ BroadcastChatDeath = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtDeath. Use for when a player has died." },
+ BroadcastChatFailure = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtFailure. Use for a command that failed to run because of insufficient permissions, etc." },
+ BroadcastChatFatal = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtFatal. Use for a plugin that crashed, or similar." },
+ BroadcastChatInfo = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtInfo. Use for informational messages, such as command usage." },
+ BroadcastChatJoin = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtJoin. Use for players joining the server." },
+ BroadcastChatLeave = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtLeave. Use for players leaving the server." },
+ BroadcastChatSuccess = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtSuccess. Use for success messages." },
+ BroadcastChatWarning = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtWarning. Use for concerning events, such as plugin reload etc." },
+ CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil.<br/><br/><b>NOTE</b>This function is currently unsafe, do not use!" },
FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for all players with names partially (or fully) matching the name string provided." },
+ DoWithPlayerByUUID = { Params = "PlayerUUID, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is the player with the uuid, calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|Player}}, [CallbackData])</pre> The function returns false if the player was not found, or whatever bool value the callback returned if the player was found." },
ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|cPlayer}})</pre>" },
ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cWorld|cWorld}})</pre>" },
Get = { Params = "", Return = "Root object", Notes = "(STATIC)This function returns the cRoot object." },
@@ -2353,6 +2408,7 @@ end
{ Params = "{{Vector3i|BlockCoords}}, BlockType, BlockMeta", Return = "", Notes = "Sets the block at the specified coords, without waking up the simulators or replacing the block entities for the previous block type. Do not use if the block being replaced has a block entity tied to it!" },
},
FindAndDoWithPlayer = { Params = "PlayerNameHint, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a player of a name similar to the specified name (weighted-match), calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|Player}}, [CallbackData])</pre> The function returns false if the player was not found, or whatever bool value the callback returned if the player was found. Note that the name matching is very loose, so it is a good idea to check the player name in the callback function." },
+ DoWithPlayerByUUID = { Params = "PlayerUUID, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is the player with the uuid, calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|Player}}, [CallbackData])</pre> The function returns false if the player was not found, or whatever bool value the callback returned if the player was found." },
ForEachBlockEntityInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each block entity in the chunk. Returns true if all block entities in the chunk have been processed (including when there are zero block entities), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBlockEntity|BlockEntity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next block entity, or true to abort the enumeration. Use {{tolua}}.cast() to cast the Callback's BlockEntity parameter to the correct {{cBlockEntity}} descendant." },
ForEachChestInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each chest in the chunk. Returns true if all chests in the chunk have been processed (including when there are zero chests), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cChestEntity|ChestEntity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next chest, or true to abort the enumeration." },
ForEachEntity = { Params = "CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each entity in the loaded world. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
@@ -2444,7 +2500,7 @@ end
SetCommandBlocksEnabled = { Params = "IsEnabled (bool)", Return = "", Notes = "Sets whether command blocks should be enabled on the (entire) server." },
SetShouldUseChatPrefixes = { Params = "", Return = "ShouldUse (bool)", Notes = "Sets whether coloured chat prefixes such as [INFO] is used with the SendMessageXXX() or BroadcastChatXXX(), or simply the entire message is coloured in the respective colour." },
ShouldUseChatPrefixes = { Params = "", Return = "bool", Notes = "Returns whether coloured chat prefixes are prepended to chat messages or the entire message is simply coloured." },
- SetSignLines = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil. Same as UpdateSign()." },
+ SetSignLines = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil." },
SetTicksUntilWeatherChange = { Params = "NumTicks", Return = "", Notes = "Sets the number of ticks after which the weather will be changed." },
SetTimeOfDay = { Params = "TimeOfDayTicks", Return = "", Notes = "Sets the time of day, expressed as number of ticks past sunrise, in the range 0 .. 24000." },
SetWeather = { Params = "Weather", Return = "", Notes = "Sets the current weather (wSunny, wRain, wStorm) and resets the TicksUntilWeatherChange to the default value for the new weather. The normal weather-changing hooks are called for the change." },
@@ -2459,7 +2515,7 @@ end
SpawnExperienceOrb = { Params = "X, Y, Z, Reward", Return = "EntityID", Notes = "Spawns an {{cExpOrb|experience orb}} at the specified coords, with the given reward" },
SpawnPrimedTNT = { Params = "X, Y, Z, FuseTicks, InitialVelocityCoeff", Return = "", Notes = "Spawns a {{cTNTEntity|primed TNT entity}} at the specified coords, with the given fuse ticks. The entity gets a random speed multiplied by the InitialVelocityCoeff, 1 being the default value." },
TryGetHeight = { Params = "BlockX, BlockZ", Return = "IsValid, Height", Notes = "Returns true and height of the highest non-air block if the chunk is loaded, or false otherwise." },
- UpdateSign = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil. Same as SetSignLiens()" },
+ UpdateSign = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "(<b>DEPRECATED</b>) Please use SetSignLines()." },
UseBlockEntity = { Params = "{{cPlayer|Player}}, BlockX, BlockY, BlockZ", Return = "", Notes = "Makes the specified Player use the block entity at the specified coords (open chest UI, etc.) If the cords are in an unloaded chunk or there's no block entity, ignores the call." },
WakeUpSimulators = { Params = "BlockX, BlockY, BlockZ", Return = "", Notes = "Wakes up the simulators for the specified block." },
WakeUpSimulatorsInArea = { Params = "MinBlockX, MaxBlockX, MinBlockY, MaxBlockY, MinBlockZ, MaxBlockZ", Return = "", Notes = "Wakes up the simulators for all the blocks in the specified area (edges inclusive)." },
@@ -2814,7 +2870,7 @@ end
Globals =
{
Desc = [[
- These functions are available directly, without a class instance. Any plugin cal call them at any
+ These functions are available directly, without a class instance. Any plugin can call them at any
time.
]],
Functions =
diff --git a/MCServer/Plugins/APIDump/Classes/Projectiles.lua b/MCServer/Plugins/APIDump/Classes/Projectiles.lua
index 08c981e5d..748f58b71 100644
--- a/MCServer/Plugins/APIDump/Classes/Projectiles.lua
+++ b/MCServer/Plugins/APIDump/Classes/Projectiles.lua
@@ -35,12 +35,49 @@ return
Inherits = "cProjectileEntity",
}, -- cArrowEntity
+ cExpBottleEntity =
+ {
+ Desc = [[
+ Represents a thrown ExpBottle. A subclass of the {{cProjectileEntity}}.
+ ]],
+ Functions =
+ {
+ },
+ Inherits = "cProjectileEntity",
+ }, -- cExpBottleEntity
+
cFireChargeEntity =
{
- Desc = "",
+ Desc = [[
+ Represents a fire charge that has been shot by a Blaze or a {{cDispenserEntity|Dispenser}}. A subclass
+ of the {{cProjectileEntity}}.
+ ]],
Functions = {},
Inherits = "cProjectileEntity",
}, -- cFireChargeEntity
+
+ cFireworkEntity =
+ {
+ Desc = [[
+ Represents a firework rocket.
+ ]],
+ Functions =
+ {
+ GetItem = { Params = "", Return = "{{cItem}}", Notes = "Returns the item that has been used to create the firework rocket. The item's m_FireworkItem member contains all the firework-related data." },
+ GetTicksToExplosion = { Params = "", Return = "number", Notes = "Returns the number of ticks left until the firework explodes." },
+ SetItem = { Params = "{{cItem}}", Return = "", Notes = "Sets a new item to be used for the firework." },
+ SetTicksToExplosion = { Params = "NumTicks", Return = "", Notes = "Sets the number of ticks left until the firework explodes." },
+ },
+
+ Inherits = "cProjectileEntity",
+ }, -- cFireworkEntity
+
+ cFloater =
+ {
+ Desc = "",
+ Functions = {},
+ Inherits = "cProjectileEntity",
+ }, -- cFloater
cGhastFireballEntity =
{
@@ -64,14 +101,14 @@ return
pkArrow = { Notes = "The projectile is an {{cArrowEntity|arrow}}" },
pkEgg = { Notes = "The projectile is a {{cThrownEggEntity|thrown egg}}" },
pkEnderPearl = { Notes = "The projectile is a {{cThrownEnderPearlEntity|thrown enderpearl}}" },
- pkExpBottle = { Notes = "The projectile is a thrown exp bottle (NYI)" },
+ pkExpBottle = { Notes = "The projectile is a {{cExpBottleEntity|thrown exp bottle}}" },
pkFireCharge = { Notes = "The projectile is a {{cFireChargeEntity|fire charge}}" },
- pkFirework = { Notes = "The projectile is a (flying) firework (NYI)" },
- pkFishingFloat = { Notes = "The projectile is a fishing float (NYI)" },
+ pkFirework = { Notes = "The projectile is a (flying) {{cFireworkEntity|firework}}" },
+ pkFishingFloat = { Notes = "The projectile is a {{cFloater|fishing float}}" },
pkGhastFireball = { Notes = "The projectile is a {{cGhastFireballEntity|ghast fireball}}" },
pkSnowball = { Notes = "The projectile is a {{cThrownSnowballEntity|thrown snowball}}" },
- pkSplashPotion = { Notes = "The projectile is a thrown splash potion (NYI)" },
- pkWitherSkull = { Notes = "The projectile is a wither skull (NYI)" },
+ pkSplashPotion = { Notes = "The projectile is a {{cSplashPotionEntity|thrown splash potion}}" },
+ pkWitherSkull = { Notes = "The projectile is a {{cWitherSkullEntity|wither skull}}" },
},
ConstantGroups =
{
@@ -84,26 +121,52 @@ return
Inherits = "cEntity",
}, -- cProjectileEntity
+ cSplashPotionEntity =
+ {
+ Desc = [[
+ Represents a thrown splash potion.
+ ]],
+ Functions =
+ {
+ GetEntityEffect = { Params = "", Return = "{{cEntityEffect}}", Notes = "Returns the entity effect in this potion" },
+ GetEntityEffectType = { Params = "", Return = "{{cEntityEffect|Entity effect type}}", Notes = "Returns the effect type of this potion" },
+ GetPotionColor = { Params = "", Return = "number", Notes = "Returns the color index of the particles emitted by this potion" },
+ SetEntityEffect = { Params = "{{cEntityEffect}}", Return = "", Notes = "Sets the entity effect for this potion" },
+ SetEntityEffectType = { Params = "{{cEntityEffect|Entity effect type}}", Return = "", Notes = "Sets the effect type of this potion" },
+ SetPotionColor = { Params = "number", Return = "", Notes = "Sets the color index of the particles for this potion" },
+ },
+ Inherits = "cProjectileEntity",
+ }, -- cSplashPotionEntity
+
cThrownEggEntity =
{
- Desc = "",
+ Desc = [[
+ Represents a thrown egg.
+ ]],
Functions = {},
Inherits = "cProjectileEntity",
}, -- cThrownEggEntity
cThrownEnderPearlEntity =
{
- Desc = "",
+ Desc = "Represents a thrown ender pearl.",
Functions = {},
Inherits = "cProjectileEntity",
}, -- cThrownEnderPearlEntity
-
+
cThrownSnowballEntity =
{
- Desc = "",
+ Desc = "Represents a thrown snowball.",
Functions = {},
Inherits = "cProjectileEntity",
}, -- cThrownSnowballEntity
+
+ cWitherSkullEntity =
+ {
+ Desc = "Represents a wither skull being shot.",
+ Functions = {},
+ Inherits = "cProjectileEntity",
+ }, -- cWitherSkullEntity
}
diff --git a/MCServer/Plugins/APIDump/Hooks/OnServerPing.lua b/MCServer/Plugins/APIDump/Hooks/OnServerPing.lua
new file mode 100644
index 000000000..76b6d1517
--- /dev/null
+++ b/MCServer/Plugins/APIDump/Hooks/OnServerPing.lua
@@ -0,0 +1,50 @@
+return
+{
+ HOOK_SERVER_PING =
+ {
+ CalledWhen = "Client pings the server from the server list.",
+ DefaultFnName = "OnServerPing", -- also used as pagename
+ Desc = [[
+ A plugin may implement an OnServerPing() function and register it as a Hook to process pings from
+ clients in the server server list. It can change the logged in players and player capacity, as well
+ as the server description and the favicon, that are displayed to the client in the server list.
+ ]],
+ Params = {
+ { Name = "ClientHandle", Type = "{{cClientHandle}}", Notes = "The client handle that pinged the server" },
+ { Name = "ServerDescription", Type = "string", Notes = "The server description" },
+ { Name = "OnlinePlayersCount", Type = "number", Notes = "The number of players currently on the server" },
+ { Name = "MaxPlayersCount", Type = "number", Notes = "The current player cap for the server" },
+ { Name = "Favicon", Type = "string", Notes = "The base64 encoded favicon to be displayed in the server list for compatible clients" },
+ },
+ Returns = [[
+ The plugin can return whether to continue processing of the hook with other plugins, the server description to
+ be displayed to the client, the currently online players, the player cap and the base64/png favicon data, in that order.
+ ]],
+ CodeExamples = {
+ {
+ Title = "Change information returned to the player",
+ Desc = "Tells the client that the server description is 'test', there are one more players online than there actually are, and that the player cap is zero. It also changes the favicon data.",
+ Code = [[
+function OnServerPing(ClientHandle, ServerDescription, OnlinePlayers, MaxPlayers, Favicon)
+ -- Change Server Description
+ ServerDescription = "Test"
+
+ -- Change online / max players
+ OnlinePlayers = OnlinePlayers + 1
+ MaxPlayers = 0
+
+ -- Change favicon
+ if cFile:IsFile("my-favicon.png") then
+ local FaviconData = cFile:ReadWholeFile("my-favicon.png")
+ if (FaviconData ~= "") and (FaviconData ~= nil) then
+ Favicon = Base64Encode(FaviconData)
+ end
+ end
+
+ return false, ServerDescription, OnlinePlayers, MaxPlayers, Favicon
+end
+ ]],
+ },
+ },
+ }, -- HOOK_SERVER_PING
+}
diff --git a/MCServer/Plugins/ChatLog b/MCServer/Plugins/ChatLog
new file mode 160000
+Subproject 983d23ca37baa89f7e4dc11d71502d9c059f637
diff --git a/MCServer/Plugins/ChatLog/plugin.lua b/MCServer/Plugins/ChatLog/plugin.lua
deleted file mode 100644
index adbf986e0..000000000
--- a/MCServer/Plugins/ChatLog/plugin.lua
+++ /dev/null
@@ -1,31 +0,0 @@
-
--- plugin.lua
-
--- Implements the main entrypoint for the plugin, as well as all the handling needed
-
--- ChatLog plugin logs all chat messages into the server log
-
-
-
-
-
-function Initialize(Plugin)
- Plugin:SetName("ChatLog")
- Plugin:SetVersion(3)
-
- cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChat)
-
- LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
- return true
-end
-
-
-
-
-
-function OnChat(Player, Message)
- -- Lets get loggin'
- LOGINFO("[" .. Player:GetName() .. "]: " .. StripColorCodes(Message));
-
- return false
-end \ No newline at end of file
diff --git a/MCServer/Plugins/ChunkWorx b/MCServer/Plugins/ChunkWorx
new file mode 160000
+Subproject 894c7e32049e9d2a1e736f7d721aaacd1ae29e5
diff --git a/MCServer/Plugins/ChunkWorx/ChunkWorx.deproj b/MCServer/Plugins/ChunkWorx/ChunkWorx.deproj
deleted file mode 100644
index 17420d1d7..000000000
--- a/MCServer/Plugins/ChunkWorx/ChunkWorx.deproj
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<project>
- <file>
- <filename>chunkworx_main.lua</filename>
- </file>
- <file>
- <filename>chunkworx_web.lua</filename>
- </file>
-</project>
diff --git a/MCServer/Plugins/ChunkWorx/chunkworx_main.lua b/MCServer/Plugins/ChunkWorx/chunkworx_main.lua
deleted file mode 100644
index 88ecb3979..000000000
--- a/MCServer/Plugins/ChunkWorx/chunkworx_main.lua
+++ /dev/null
@@ -1,128 +0,0 @@
--- Global variables
-PLUGIN = {} -- Reference to own plugin object
-GENERATION_STATE = 0
-OPERATION_CODE = 0 -- 0 = generation
-CX = 0
-CZ = 0
-CURRENT = 0
-TOTAL = 0
-
--- AREA Variables
-AreaStartX = -10
-AreaStartZ = -10
-AreaEndX = 10
-AreaEndZ = 10
-
--- RADIAL Variables
-RadialX = 0
-RadialZ = 0
-Radius = 10
-
--- WORLD
-WORK_WORLD = cRoot:Get():GetDefaultWorld():GetName()
-WW_instance = cRoot:Get():GetDefaultWorld()
-WORLDS = {}
-
-
-
-
-
-function Initialize(Plugin)
- PLUGIN = Plugin
-
- PLUGIN:SetName("ChunkWorx")
- PLUGIN:SetVersion(6)
-
- cPluginManager.AddHook(cPluginManager.HOOK_TICK, OnTick)
-
- Plugin:AddWebTab("(Re)Generation", HandleRequest_Generation)
-
- GENERATION_STATE = 0
- WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
- if (WW_instance == nil) then
- LOG("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": NO WORLD found :(")
- end
-
- -- Read the stored values:
- local SettingsIni = cIniFile();
- SettingsIni:ReadFile("ChunkWorx.ini"); -- ignore any read errors
- AreaStartX = SettingsIni:GetValueSetI("Area data", "StartX", AreaStartX)
- AreaStartZ = SettingsIni:GetValueSetI("Area data", "StartZ", AreaStartZ)
- AreaEndX = SettingsIni:GetValueSetI("Area data", "EndX", AreaEndX)
- AreaEndZ = SettingsIni:GetValueSetI("Area data", "EndZ", AreaEndZ)
- RadialX = SettingsIni:GetValueSetI("Radial data", "RadialX", RadialX)
- RadialZ = SettingsIni:GetValueSetI("Radial data", "RadialZ", RadialZ)
- Radius = SettingsIni:GetValueSetI("Radial data", "Radius", Radius)
- SettingsIni:WriteFile("ChunkWorx.ini");
-
- LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion())
- return true
-end
-
-
-
-
-
-function OnTick( DeltaTime )
- if (GENERATION_STATE == 1 or GENERATION_STATE == 3) then
- LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works STARTED!")
- LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": At world: " .. WORK_WORLD)
- WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
- if (GENERATION_STATE == 1) then GENERATION_STATE = 2 end
- if (GENERATION_STATE == 3) then GENERATION_STATE = 4 end
-
- -- Changing in case coordinates are flipped
- local shifter = AreaEndX
- if (AreaStartX > AreaEndX) then
- AreaEndX = AreaStartX
- AreaStartX = shifter
- end
- shifter = AreaEndZ
- if (AreaStartZ > AreaEndZ) then
- AreaEndZ = AreaStartZ
- AreaStartZ = shifter
- end
-
- CX = AreaStartX
- CZ = AreaStartZ
- CURRENT = 0
-
- if (WW_instance == nil) then
- LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED")
- LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": NO WORLD found :(")
- GENERATION_STATE = 0
- end
- end
-
-
-
- if (GENERATION_STATE == 2 or GENERATION_STATE == 4) then
- if (WW_instance:GetGeneratorQueueLength() < 200
- and WW_instance:GetLightingQueueLength() < 200
- and (WW_instance:GetStorageSaveQueueLength() + WW_instance:GetStorageLoadQueueLength()) < 80) then
- local chunk_sum = (1+ AreaEndX - AreaStartX) * (1+ AreaEndZ - AreaStartZ)
- TOTAL = chunk_sum
- LOG("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": PROCESSING 100 chunks, (" .. CURRENT .. "/" .. chunk_sum .. ")")
- for C = 1, 100 do
- if (GENERATION_STATE == 2) then WW_instance:GenerateChunk(CX, CZ) end
- if (GENERATION_STATE == 4) then WW_instance:RegenerateChunk(CX, CZ) end
-
- CX = CX + 1
- CURRENT = CURRENT + 1
- if (CX > AreaEndX) then
- CX = AreaStartX
- CZ = CZ + 1
- if (CZ > AreaEndZ) then
- if (GENERATION_STATE == 2) then LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " - generation ENDED!") end
- if (GENERATION_STATE == 4) then LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " - REgeneration ENDED!") end
-
- GENERATION_STATE = 0
- break
- end
- end
- end
- WW_instance:QueueSaveAllChunks()
- WW_instance:QueueUnloadUnusedChunks()
- end
- end
-end \ No newline at end of file
diff --git a/MCServer/Plugins/ChunkWorx/chunkworx_web.lua b/MCServer/Plugins/ChunkWorx/chunkworx_web.lua
deleted file mode 100644
index 9aec38b12..000000000
--- a/MCServer/Plugins/ChunkWorx/chunkworx_web.lua
+++ /dev/null
@@ -1,274 +0,0 @@
-
--- chunkworx_web.lua
-
--- WebAdmin-related functions
-
-
-
-
-
-local function Buttons_Player( Name )
- return "<form method='POST'><input type='hidden' name='PlayerName' value='"..Name.."'><input type='submit' name='PlayerExact' value='Exact'><input type='submit' name='Player3x3' value='3x3'></form>"
-end
-
-
-
-
-
-local function Button_World( Name )
- return "<form method='POST'><input type='hidden' name='WorldName' value='"..Name.."'><input type='submit' name='SelectWorld' value='Select'></form>"
-end
-
-
-
-
-
-local function SaveSettings()
- local SettingsIni = cIniFile()
- SettingsIni:SetValueI("Area data", "StartX", AreaStartX)
- SettingsIni:SetValueI("Area data", "StartZ", AreaStartZ)
- SettingsIni:SetValueI("Area data", "EndX", AreaEndX)
- SettingsIni:SetValueI("Area data", "EndZ", AreaEndZ)
- SettingsIni:SetValueI("Radial data", "RadialX", RadialX)
- SettingsIni:SetValueI("Radial data", "RadialZ", RadialZ)
- SettingsIni:SetValueI("Radial data", "Radius", Radius)
- SettingsIni:WriteFile("ChunkWorx.ini")
-end
-
-
-
-
-
-function HandleRequest_Generation( Request )
- local Content = ""
- if (Request.PostParams["AGHRRRR"] ~= nil) then
- GENERATION_STATE = 0
- WW_instance:QueueSaveAllChunks()
- WW_instance:QueueUnloadUnusedChunks()
- LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED by admin")
- end
- --Content = Content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
- -- PROCESSING
- --------------------------------------------------------------------------------------------------
- local function ProcessingContent()
- local _small_content = ""
- _small_content = _small_content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
- _small_content = _small_content .. "<h4>World for operations:</h4>"..WORK_WORLD
- if (OPERATION_CODE == 0) then
- _small_content = _small_content .. "<h4>Operation:</h4>Generation"
- elseif (OPERATION_CODE == 1) then
- _small_content = _small_content .. "<h4>Operation:</h4>Regeneration"
- end
- _small_content = _small_content .. "<h4>Area: </h4>["..AreaStartX..":"..AreaStartZ.."] ["..AreaEndX..":"..AreaEndZ.."]"
- _small_content = _small_content .. "<h4>Progress:</h4>"..CURRENT.."/"..TOTAL
- _small_content = _small_content .. "<br>"
- _small_content = _small_content .. "<form method='POST'>"
- _small_content = _small_content .. "<input type='submit' name='AGHRRRR' value='Stop'>"
- _small_content = _small_content .. "</form>"
- return _small_content
- end
- if (GENERATION_STATE == 2 or GENERATION_STATE == 4) then
- Content = ProcessingContent()
- return Content
- end
- -- SELECTING
- --------------------------------------------------------------------------------------------------
- if ( Request.PostParams["FormSetWorld"] ) then
- WORK_WORLD = Request.PostParams["FormWorldName"]
- WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
- end
-
- if( Request.PostParams["SelectWorld"] ~= nil
- and Request.PostParams["WorldName"] ~= nil ) then -- World is selected!
- WORK_WORLD = Request.PostParams["WorldName"]
- WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
- end
-
- if(Request.PostParams["OperationGenerate"] ~= nil) then
- OPERATION_CODE = 0
- end
- if(Request.PostParams["OperationReGenerate"] ~= nil) then
- OPERATION_CODE = 1
- end
-
- if (GENERATION_STATE == 0) then
- if( Request.PostParams["FormAreaStartX"] ~= nil
- and Request.PostParams["FormAreaStartZ"] ~= nil
- and Request.PostParams["FormAreaEndX"] ~= nil
- and Request.PostParams["FormAreaEndZ"] ~= nil ) then --(Re)Generation valid!
- -- COMMON (Re)gen
- if( Request.PostParams["StartArea"]) then
- AreaStartX = tonumber(Request.PostParams["FormAreaStartX"])
- AreaStartZ = tonumber(Request.PostParams["FormAreaStartZ"])
- AreaEndX = tonumber(Request.PostParams["FormAreaEndX"])
- AreaEndZ = tonumber(Request.PostParams["FormAreaEndZ"])
- SaveSettings();
- if (OPERATION_CODE == 0) then
- GENERATION_STATE = 1
- elseif (OPERATION_CODE == 1) then
- GENERATION_STATE = 3
- end
- Content = ProcessingContent()
- return Content
- end
- end
- if( Request.PostParams["FormRadialX"] ~= nil
- and Request.PostParams["FormRadialZ"] ~= nil
- and Request.PostParams["FormRadius"] ~= nil ) then --(Re)Generation valid!
- -- COMMON (Re)gen
- if( Request.PostParams["StartRadial"]) then
- RadialX = tonumber(Request.PostParams["FormRadialX"]) or 0
- RadialZ = tonumber(Request.PostParams["FormRadialZ"]) or 0
- Radius = tonumber(Request.PostParams["FormRadius"]) or 10
- AreaStartX = RadialX - Radius
- AreaStartZ = RadialZ - Radius
- AreaEndX = RadialX + Radius
- AreaEndZ = RadialZ + Radius
- SaveSettings()
- if (OPERATION_CODE == 0) then
- GENERATION_STATE = 1
- elseif (OPERATION_CODE == 1) then
- GENERATION_STATE = 3
- end
- Content = ProcessingContent()
- return Content
- end
- end
- -- POINT REGEN!
- if( Request.PostParams["FormPointX"] ~= nil
- and Request.PostParams["FormPointZ"] ~= nil ) then --ReGeneration valid!
- -- EXACT
- if ( Request.PostParams["PointExact"] ~= nil) then
- AreaStartX = tonumber(Request.PostParams["FormPointX"])
- AreaStartZ = tonumber(Request.PostParams["FormPointZ"])
- AreaEndX = AreaStartX
- AreaEndZ = AreaStartZ
- GENERATION_STATE = 3
- Content = ProcessingContent()
- return Content
- end
- -- 3x3
- if ( Request.PostParams["Point3x3"] ~= nil) then
- AreaStartX = tonumber(Request.PostParams["FormPointX"]) - 1
- AreaStartZ = tonumber(Request.PostParams["FormPointZ"]) - 1
- AreaEndX = AreaStartX + 2
- AreaEndZ = AreaStartZ + 2
- GENERATION_STATE = 3
- Content = ProcessingContent()
- return Content
- end
- end
-
- local GetAreaByPlayer = function(Player)
- -- Player is valid only within this function, it cannot be stord and used later!
- AreaStartX = Player:GetChunkX()
- AreaStartZ = Player:GetChunkZ()
- end
- -- PLAYERS REGEN!
- if( Request.PostParams["PlayerExact"] ~= nil
- and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
- cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
- AreaEndX = AreaStartX
- AreaEndZ = AreaStartZ
- GENERATION_STATE = 3
- Content = ProcessingContent()
- return Content
- end
- if( Request.PostParams["Player3x3"] ~= nil
- and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
- cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
- AreaStartX = AreaStartX - 1
- AreaStartZ = AreaStartZ - 1
- AreaEndX = AreaStartX + 2
- AreaEndZ = AreaStartZ + 2
- GENERATION_STATE = 3
- Content = ProcessingContent()
- return Content
- end
- end
-
- --Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
- --Content = Content .. "<form method='POST'>"
- --Content = Content .. "<input type='text' name='FormWorldName' value='Input world name here'><input type='submit' name='FormSetWorld' value='Set world'>"
- --Content = Content .. "</form>"
-
- -- SELECTING WORK_WORLD
- Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
- Content = Content .. "<table>"
- local WorldNum = 0
- local AddWorldToTable = function(World)
- WorldNum = WorldNum + 1
- Content = Content .. "<tr>"
- Content = Content .. "<td style='width: 10px;'>" .. WorldNum .. ".</td>"
- Content = Content .. "<td>" .. World:GetName() .. "</td>"
- Content = Content .. "<td>" .. Button_World(World:GetName()) .. "</td>"
- Content = Content .. "</tr>"
- end
- cRoot:Get():ForEachWorld(AddWorldToTable)
- if( WorldNum == 0 ) then
- Content = Content .. "<tr><td>No worlds! O_O</td></tr>"
- end
- Content = Content .. "</table>"
- Content = Content .. "<br>"
-
- -- SELECTING OPERATION
- if (OPERATION_CODE == 0) then
- Content = Content .. "<h4>Operation: Generation</h4>"
- elseif (OPERATION_CODE == 1) then
- Content = Content .. "<h4>Operation: Regeneration</h4>"
- end
- Content = Content .. "<form method='POST'>"
- Content = Content .. "<input type='submit' name='OperationGenerate' value='Generation'>"
- Content = Content .. "<input type='submit' name='OperationReGenerate' value='Regeneration'>"
- Content = Content .. "</form>"
-
- -- SELECTING AREA
- Content = Content .. "<h4>Area: </h4>Start X, Start Z; End X, End Z"
- Content = Content .. "<form method='POST'>"
- Content = Content .. "<input type='text' name='FormAreaStartX' value='" .. AreaStartX .. "'><input type='text' name='FormAreaStartZ' value='" .. AreaStartZ .. "'>"
- Content = Content .. "<input type='text' name='FormAreaEndX' value='" .. AreaEndX .. "'><input type='text' name='FormAreaEndZ' value='" .. AreaEndZ .. "'>"
- Content = Content .. "<input type='submit' name='StartArea' value='Start'>"
- Content = Content .. "</form>"
-
- -- SELECTING RADIAL
- Content = Content .. "<h4>Radial: </h4>Center X, Center Z, Radius"
- Content = Content .. "<form method='POST'>"
- Content = Content .. "<input type='text' name='FormRadialX' value='" .. RadialX .. "'><input type='text' name='FormRadialZ' value='" .. RadialZ .. "'><input type='text' name='FormRadius' value='" .. Radius .. "'>"
- Content = Content .. "<input type='submit' name='StartRadial' value='Start'>"
- Content = Content .. "</form>"
- Content = Content .. "<br>"
- Content = Content .. "<br>"
- Content = Content .. "<br>"
-
- -- SELECTING POINT
- Content = Content .. "<h4>Point regeneration:</h4> X, Z"
- Content = Content .. "<form method='POST'>"
- Content = Content .. "<input type='text' name='FormPointX' value='0'><input type='text' name='FormPointZ' value='0'>"
- Content = Content .. "<input type='submit' name='PointExact' value='Exact'>"
- Content = Content .. "<input type='submit' name='Point3x3' value='3x3'>"
- Content = Content .. "</form>"
-
- -- SELECTING PLAYERS
- Content = Content .. "<h4>Player-based regeneration:</h4>"
- 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>" .. Buttons_Player(Player:GetName()) .. "</td>"
- Content = Content .. "</tr>"
- end
- if (cRoot:Get():GetWorld(WORK_WORLD) == nil) then
- Content = Content .. "<tr><td>Incorrect world selection</td></tr>"
- else
- cRoot:Get():GetWorld(WORK_WORLD):ForEachPlayer( AddPlayerToTable )
- if( PlayerNum == 0 ) then
- Content = Content .. "<tr><td>No connected players</td></tr>"
- end
- end
- Content = Content .. "</table>"
- Content = Content .. "<br>"
- return Content
-end \ No newline at end of file
diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core
-Subproject bd23915df763b182610c6163c5ff2d64a075656
+Subproject 4702471943511f641458c7e8e89b430a723f43e
diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua
index f66ac76a0..3dcd4ebee 100644
--- a/MCServer/Plugins/Debuggers/Debuggers.lua
+++ b/MCServer/Plugins/Debuggers/Debuggers.lua
@@ -10,9 +10,6 @@ g_ShowFoodStats = false; -- When true, each player's food stats are sent to the
function Initialize(Plugin)
- Plugin:SetName("Debuggers")
- Plugin:SetVersion(1)
-
--[[
-- Test multiple hook handlers:
cPluginManager.AddHook(cPluginManager.HOOK_TICK, OnTick1);
@@ -68,6 +65,8 @@ function Initialize(Plugin)
PM:BindCommand("/rmitem", "debuggers", HandleRMItem, "- Remove the specified item from the inventory.");
PM:BindCommand("/pickups", "debuggers", HandlePickups, "- Spawns random pickups around you");
PM:BindCommand("/poof", "debuggers", HandlePoof, "- Nudges pickups close to you away from you");
+
+ PM:BindConsoleCommand("sched", HandleConsoleSchedule, "Tests the world scheduling");
Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers)
Plugin:AddWebTab("StressTest", HandleRequest_StressTest)
@@ -1630,3 +1629,17 @@ end
+
+function HandleConsoleSchedule(a_Split)
+ LOG("Scheduling a task for 2 seconds in the future")
+ cRoot:Get():GetDefaultWorld():ScheduleTask(40,
+ function ()
+ LOG("Scheduled function is called.")
+ end
+ )
+ return true, "Task scheduled"
+end
+
+
+
+
diff --git a/MCServer/Plugins/Handy b/MCServer/Plugins/Handy
new file mode 160000
+Subproject e64a04be39ac7790abcb09de3d4c7d8fc2a2a1e
diff --git a/MCServer/Plugins/Handy/handy.lua b/MCServer/Plugins/Handy/handy.lua
deleted file mode 100644
index e4e9d3f5f..000000000
--- a/MCServer/Plugins/Handy/handy.lua
+++ /dev/null
@@ -1,28 +0,0 @@
--- Global variables
-PLUGIN = {} -- Reference to own plugin object
-CHEST_WIDTH = 9
-HANDY_VERSION = 2
---[[
-
-Handy is a plugin for other plugins. It contain no commands, no hooks, but functions to ease plugins developers' life.
-
-API:
-
-
-TODO:
-1. GetChestSlot wrapper, so it will detect double chest neighbour chest and will be able to access it.
-]]
-
-function Initialize(Plugin)
- PLUGIN = Plugin
- PLUGIN:SetName("Handy")
- PLUGIN:SetVersion(HANDY_VERSION)
-
- PluginManager = cRoot:Get():GetPluginManager()
- LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion())
- return true
-end
-
-function OnDisable()
- LOG(PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " is shutting down...")
-end \ No newline at end of file
diff --git a/MCServer/Plugins/Handy/handy_functions.lua b/MCServer/Plugins/Handy/handy_functions.lua
deleted file mode 100644
index af43f663a..000000000
--- a/MCServer/Plugins/Handy/handy_functions.lua
+++ /dev/null
@@ -1,216 +0,0 @@
---[[
-General stuff
-]]
--- Returns Handy plugin version number
-function GetHandyVersion()
- return HANDY_VERSION
-end
--- Checks if handy is in proper version
-function CheckForRequiredVersion( inVersion )
- if( inVersion > HANDY_VERSION ) then return false end
- return true
-end
---[[
-MCS-specific _functions and nasty hacks :D
-]]
-function GetChestHeightCheat( inChest )
- local chestGrid = inChest:GetContents()
- LOGINFO( "This function serves no purpose now! You should consider chest:GetContents():GetHeight() now!" )
- LOGINFO( "Also, you might find Handy's new 'IsChestDouble()' useful for your case" )
- return chestGrid:GetHeight()
-end
-function IsChestDouble( inChest )
- local chestHeight = inChest:GetContents():GetHeight()
- if( chestHeight == 3 ) then
- return false
- end
- return true
-end
--- Those two checks how many items of given inItemID chest and player have, and how much they could fit inside them
-function ReadChestForItem( inChest, inItemID )
- return ReadGridForItems( inChest:GetContents(), inItemID )
-end
-function ReadPlayerForItem( inPlayer, inItemID )
- local inventoryFound, inventoryFree = ReadGridForItems( inPlayer:GetInventory():GetInventoryGrid(), inItemID )
- local hotbarFound, hotbarFree = ReadGridForItems( inPlayer:GetInventory():GetHotbarGrid(), inItemID )
- local itemsFound = inventoryFound + hotbarFound
- local freeSpace = inventoryFree + hotbarFree
- return itemsFound, freeSpace
-end
--- Following functions are for chest-related operations
--- BEWARE! Those assume you did checked if chest has items/space in it!
-function ReadGridForItems( inGrid, inItemID )
- local itemsFound = 0
- local freeSpace = 0
- local slotsCount = inGrid:GetNumSlots()
- local testerItem = cItem( inItemID )
- local maxStackSize = testerItem:GetMaxStackSize()
- for index = 0, (slotsCount - 1) do
- slotItem = inGrid:GetSlot( index )
- if( slotItem:IsEmpty() ) then
- freeSpace = freeSpace + maxStackSize
- else
- if( slotItem:IsStackableWith( testerItem ) ) then
- itemsFound = itemsFound + slotItem.m_ItemCount
- freeSpace = maxStackSize - slotItem.m_ItemCount
- end
- end
- end
- return itemsFound, freeSpace
-end
-
-function TakeItemsFromGrid( inGrid, inItem )
- local slotsCount = inGrid:GetNumSlots()
- local removedItem = cItem( inItem )
- for index = 0, (slotsCount - 1) do
- slotItem = inGrid:GetSlot( index )
- if( slotItem:IsSameType( removedItem ) ) then
- if( slotItem.m_ItemCount <= removedItem.m_ItemCount ) then
- removedItem.m_ItemCount = removedItem.m_ItemCount - slotItem.m_ItemCount
- inGrid:EmptySlot( index )
- else
- removedItem.m_ItemCount = slotItem.m_ItemCount - removedItem.m_ItemCount
- inGrid:SetSlot( index, removedItem )
- removedItem.m_ItemCount = 0
- end
- if( removedItem.m_ItemCount <= 0 ) then break end
- end
- end
- return removedItem.m_ItemCount
-end
---------------
-function TakeItemsFromChest( inChest, inItemID, inAmount ) -- MIGHT BE UNSAFE! CHECK FOR ITEMS FIRST!!
- local chestGrid = inChest:GetContents()
- local removedItem = cItem( inItemID, inAmount )
- TakeItemsFromGrid( chestGrid, removedItem )
-end
-function PutItemsToChest( inChest, inItemID, inAmount )
- local chestGrid = inChest:GetContents()
- local addedItem = cItem( inItemID, inAmount )
- chestGrid:AddItem( addedItem )
-end
--- Similar to chest-related.
-function TakeItemsFromPlayer( inPlayer, inItemID, inAmount ) -- MIGHT BE UNSAFE! CHECK FIRST!
- local removedItem = cItem( inItemID, inAmount )
- local inventoryGrid = inPlayer:GetInventory():GetInventoryGrid()
- local hotbarGrid = inPlayer:GetInventory():GetHotbarGrid()
- local itemsLeft = TakeItemsFromGrid( inventoryGrid, removedItem )
- if( itemsLeft > 0 ) then
- removedItem = cItem( inItemID, itemsLeft )
- TakeItemsFromGrid( hotbarGrid, removedItem )
- end
-end
-function GiveItemsToPlayer( inPlayer, inItemID, inAmount )
- local addedItem = cItem( inItemID, inAmount )
- local inventoryGrid = inPlayer:GetInventory():GetInventoryGrid()
- local hotbarGrid = inPlayer:GetInventory():GetHotbarGrid()
- local itemsAdded = inventoryGrid:AddItem( addedItem )
- if( itemsAdded < inAmount ) then
- addedItem.m_ItemCount = addedItem.m_ItemCount - itemsAdded
- hotbarGrid:AddItem( addedItem )
- end
-end
--- This function returns item max stack for a given itemID. It uses vanilla max stack size, and uses several non-common items notations;
--- Those are:
--- oneonerecord( because aparently 11record wasn't the best idea in lua scripting application )
--- carrotonastick( because it wasn't added to items.txt yet )
--- waitrecord( for same reason )
--- Feel free to ignore the difference, or to add those to items.txt
-function GetItemMaxStack( inItemID )
- local testerItem = cItem( inItemID )
- LOGINFO( "This function serves no real purpose now, maybe consider using cItem:GetMaxStackSize()?" )
- return testerItem:GetMaxStackSize()
-end
-function ItemIsArmor( inItemID, inCheckForHorseArmor )
- inCheckForHorseArmor = inCheckForHorseArmor or false
- if( inItemID == E_ITEM_LEATHER_CAP ) then return true end
- if( inItemID == E_ITEM_LEATHER_TUNIC ) then return true end
- if( inItemID == E_ITEM_LEATHER_PANTS ) then return true end
- if( inItemID == E_ITEM_LEATHER_BOOTS ) then return true end
-
- if( inItemID == E_ITEM_CHAIN_HELMET ) then return true end
- if( inItemID == E_ITEM_CHAIN_CHESTPLATE ) then return true end
- if( inItemID == E_ITEM_CHAIN_LEGGINGS ) then return true end
- if( inItemID == E_ITEM_CHAIN_BOOTS ) then return true end
-
- if( inItemID == E_ITEM_IRON_HELMET ) then return true end
- if( inItemID == E_ITEM_IRON_CHESTPLATE ) then return true end
- if( inItemID == E_ITEM_IRON_LEGGINGS ) then return true end
- if( inItemID == E_ITEM_IRON_BOOTS ) then return true end
-
- if( inItemID == E_ITEM_DIAMOND_HELMET ) then return true end
- if( inItemID == E_ITEM_DIAMOND_CHESTPLATE ) then return true end
- if( inItemID == E_ITEM_DIAMOND_LEGGINGS ) then return true end
- if( inItemID == E_ITEM_DIAMOND_BOOTS ) then return true end
-
- if( inItemID == E_ITEM_GOLD_HELMET ) then return true end
- if( inItemID == E_ITEM_GOLD_CHESTPLATE ) then return true end
- if( inItemID == E_ITEM_GOLD_LEGGINGS ) then return true end
- if( inItemID == E_ITEM_GOLD_BOOTS ) then return true end
-
- if( inCheckForHorseArmor ) then
- if( inItemID == E_ITEM_IRON_HORSE_ARMOR ) then return true end
- if( inItemID == E_ITEM_GOLD_HORSE_ARMOR ) then return true end
- if( inItemID == E_ITEM_DIAMOND_HORSE_ARMOR ) then return true end
- end
- return false
-end
--- Returns full-length playername for a short name( usefull for parsing commands )
-function GetExactPlayername( inPlayerName )
- local _result = inPlayerName
- local function SetProcessingPlayername( inPlayer )
- _result = inPlayer:GetName()
- end
- cRoot:Get():FindAndDoWithPlayer( inPlayerName, SetProcessingPlayername )
- return _result
-end
-function GetPlayerByName( inPlayerName )
- local _player
- local PlayerSetter = function( Player )
- _player = Player
- end
- cRoot:Get():FindAndDoWithPlayer( inPlayerName, PlayerSetter )
- return _player
-end
---[[
-Not-so-usual math _functions
-]]
--- Rounds floating point number. Because lua guys think this function doesn't deserve to be presented in lua's math
-function round( inX )
- if( inX%2 ~= 0.5 ) then
- return math.floor( inX + 0.5 )
- end
- return inX - 0.5
-end
---[[
-Functions I use for filework and stringswork
-]]
-function PluralString( inValue, inSingularString, inPluralString )
- local _value_string = tostring( inValue )
- if( _value_string[#_value_string] == "1" ) then
- return inSingularString
- end
- return inPluralString
-end
-function PluralItemName( inItemID, inAmount ) -- BEWARE! TEMPORAL SOLUTION THERE! :D
- local _value_string = tostring( inValue )
- local _name = ""
- if( _value_string[#_value_string] == "1" ) then
- -- singular names
- _name = ItemTypeToString( inItemID )
- else
- -- plural names
- _name = ItemTypeToString( inItemID ).."s"
- end
- return _name
-end
--- for filewriting purposes. 0 = false, 1 = true
-function StringToBool( inValue )
- if( inValue == "1" ) then return true end
- return false
-end
--- same, but reversal
-function BoolToString( inValue )
- if( inValue == true ) then return 1 end
- return 0
-end
diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua
index c61f9c9e6..de1d1f451 100644
--- a/MCServer/Plugins/InfoDump.lua
+++ b/MCServer/Plugins/InfoDump.lua
@@ -20,8 +20,8 @@ only that one plugin's documentation. This mode of operation doesn't require Lua
-- Check Lua version. We use 5.1-specific construct when loading the plugin info, 5.2 is not compatible!
if (_VERSION ~= "Lua 5.1") then
- print("Unsupported Lua version. This script requires Lua version 5.1, this Lua is version " .. (_VERSION or "<nil>"));
- return;
+ print("Unsupported Lua version. This script requires Lua version 5.1, this Lua is version " .. (_VERSION or "<nil>"))
+ return
end
@@ -31,38 +31,38 @@ end
--- Replaces generic formatting with forum-specific formatting
-- Also removes the single line-ends
local function ForumizeString(a_Str)
- assert(type(a_Str) == "string");
+ assert(type(a_Str) == "string")
-- Remove the indentation, unless in the code tag:
-- Only one code or /code tag per line is supported!
- local IsInCode = false;
+ local IsInCode = false
local function RemoveIndentIfNotInCode(s)
if (IsInCode) then
-- we're in code section, check if this line terminates it
- IsInCode = (s:find("{%%/code}") ~= nil);
- return s .. "\n";
+ IsInCode = (s:find("{%%/code}") ~= nil)
+ return s .. "\n"
else
-- we're not in code section, check if this line starts it
- IsInCode = (s:find("{%%code}") ~= nil);
- return s:gsub("^%s*", "") .. "\n";
+ IsInCode = (s:find("{%%code}") ~= nil)
+ return s:gsub("^%s*", "") .. "\n"
end
end
- a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode);
+ a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode)
-- Replace multiple line ends with {%p} and single line ends with a space,
-- so that manual word-wrap in the Info.lua file doesn't wrap in the forum.
- a_Str = a_Str:gsub("\n\n", "{%%p}");
- a_Str = a_Str:gsub("\n", " ");
+ a_Str = a_Str:gsub("\n\n", "{%%p}")
+ a_Str = a_Str:gsub("\n", " ")
-- Replace the generic formatting:
- a_Str = a_Str:gsub("{%%p}", "\n\n");
- a_Str = a_Str:gsub("{%%b}", "[b]"):gsub("{%%/b}", "[/b]");
- a_Str = a_Str:gsub("{%%i}", "[i]"):gsub("{%%/i}", "[/i]");
- a_Str = a_Str:gsub("{%%list}", "[list]"):gsub("{%%/list}", "[/list]");
- a_Str = a_Str:gsub("{%%li}", "[*]"):gsub("{%%/li}", "");
+ a_Str = a_Str:gsub("{%%p}", "\n\n")
+ a_Str = a_Str:gsub("{%%b}", "[b]"):gsub("{%%/b}", "[/b]")
+ a_Str = a_Str:gsub("{%%i}", "[i]"):gsub("{%%/i}", "[/i]")
+ a_Str = a_Str:gsub("{%%list}", "[list]"):gsub("{%%/list}", "[/list]")
+ a_Str = a_Str:gsub("{%%li}", "[*]"):gsub("{%%/li}", "")
-- TODO: Other formatting
- return a_Str;
+ return a_Str
end
@@ -72,38 +72,38 @@ end
--- Replaces generic formatting with forum-specific formatting
-- Also removes the single line-ends
local function GithubizeString(a_Str)
- assert(type(a_Str) == "string");
+ assert(type(a_Str) == "string")
-- Remove the indentation, unless in the code tag:
-- Only one code or /code tag per line is supported!
- local IsInCode = false;
+ local IsInCode = false
local function RemoveIndentIfNotInCode(s)
if (IsInCode) then
-- we're in code section, check if this line terminates it
- IsInCode = (s:find("{%%/code}") ~= nil);
- return s .. "\n";
+ IsInCode = (s:find("{%%/code}") ~= nil)
+ return s .. "\n"
else
-- we're not in code section, check if this line starts it
- IsInCode = (s:find("{%%code}") ~= nil);
- return s:gsub("^%s*", "") .. "\n";
+ IsInCode = (s:find("{%%code}") ~= nil)
+ return s:gsub("^%s*", "") .. "\n"
end
end
- a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode);
+ a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode)
-- Replace multiple line ends with {%p} and single line ends with a space,
-- so that manual word-wrap in the Info.lua file doesn't wrap in the forum.
- a_Str = a_Str:gsub("\n\n", "{%%p}");
- a_Str = a_Str:gsub("\n", " ");
+ a_Str = a_Str:gsub("\n\n", "{%%p}")
+ a_Str = a_Str:gsub("\n", " ")
-- Replace the generic formatting:
- a_Str = a_Str:gsub("{%%p}", "\n\n");
- a_Str = a_Str:gsub("{%%b}", "**"):gsub("{%%/b}", "**");
- a_Str = a_Str:gsub("{%%i}", "*"):gsub("{%%/i}", "*");
- a_Str = a_Str:gsub("{%%list}", ""):gsub("{%%/list}", "");
- a_Str = a_Str:gsub("{%%li}", " - "):gsub("{%%/li}", "");
+ a_Str = a_Str:gsub("{%%p}", "\n\n")
+ a_Str = a_Str:gsub("{%%b}", "**"):gsub("{%%/b}", "**")
+ a_Str = a_Str:gsub("{%%i}", "*"):gsub("{%%/i}", "*")
+ a_Str = a_Str:gsub("{%%list}", ""):gsub("{%%/list}", "")
+ a_Str = a_Str:gsub("{%%li}", " - "):gsub("{%%/li}", "")
-- TODO: Other formatting
- return a_Str;
+ return a_Str
end
@@ -117,7 +117,7 @@ end
local function BuildCategories(a_PluginInfo)
-- The returned result
-- This will contain both an array and a dict of the categories, to allow fast search
- local res = {};
+ local res = {}
-- For each command add a reference to it into all of its categories:
local function AddCommands(a_CmdPrefix, a_Commands)
@@ -130,39 +130,39 @@ local function BuildCategories(a_PluginInfo)
if ((info.HelpString ~= nil) and (info.HelpString ~= "")) then
-- Add to each specified category:
- local Category = info.Category;
+ local Category = info.Category
if (type(Category) == "string") then
- Category = {Category};
+ Category = {Category}
end
for idx, cat in ipairs(Category or {""}) do
- local CatEntry = res[cat];
+ local CatEntry = res[cat]
if (CatEntry == nil) then
-- First time we came across this category, create it:
- local NewCat = {Name = cat, Description = "", Commands = {NewCmd}};
- table.insert(res, NewCat);
- res[cat] = NewCat;
+ local NewCat = {Name = cat, Description = "", Commands = {NewCmd}}
+ table.insert(res, NewCat)
+ res[cat] = NewCat
else
-- We already have this category, just add the command to its list of commands:
- table.insert(CatEntry.Commands, NewCmd);
+ table.insert(CatEntry.Commands, NewCmd)
end
end -- for idx, cat - Category[]
end -- if (HelpString valid)
-- Recurse all subcommands:
if (info.Subcommands ~= nil) then
- AddCommands(a_CmdPrefix .. cmd .. " ", info.Subcommands);
+ AddCommands(a_CmdPrefix .. cmd .. " ", info.Subcommands)
end
end -- for cmd, info - a_Commands[]
end -- AddCommands()
- AddCommands("", a_PluginInfo.Commands);
+ AddCommands("", a_PluginInfo.Commands)
-- Assign descriptions to categories:
for name, desc in pairs(a_PluginInfo.Categories or {}) do
- local CatEntry = res[name];
+ local CatEntry = res[name]
if (CatEntry ~= nil) then
-- The result has this category, add the description:
- CatEntry.Description = desc.Description;
+ CatEntry.Description = desc.Description
end
end
@@ -170,12 +170,12 @@ local function BuildCategories(a_PluginInfo)
for idx, cat in ipairs(res) do
table.sort(cat.Commands,
function (cmd1, cmd2)
- return (string.lower(cmd1.CommandString) < string.lower(cmd2.CommandString));
+ return (string.lower(cmd1.CommandString) < string.lower(cmd2.CommandString))
end
- );
+ )
end
- return res;
+ return res
end
@@ -188,9 +188,9 @@ end
-- colorizes command name blue and params green
local function GetCommandRefForum(a_Command)
if (type(a_Command) == "string") then
- return "[color=blue]" .. a_Command .. "[/color]";
+ return "[color=blue]" .. a_Command .. "[/color]"
end
- return "[color=blue]" .. a_Command.Name .. "[/color] [color=green]" .. (a_Command.Params or "") .. "[/color]";
+ return "[color=blue]" .. a_Command.Name .. "[/color] [color=green]" .. (a_Command.Params or "") .. "[/color]"
end
@@ -201,18 +201,18 @@ end
-- If a_CommandParams is nil, returns a_CommandName apostrophed
-- If a_CommandParams is a string, apostrophes a_CommandName with a_CommandParams
local function GetCommandRefGithub(a_CommandName, a_CommandParams)
- assert(type(a_CommandName) == "string");
+ assert(type(a_CommandName) == "string")
if (a_CommandParams == nil) then
- return "`" .. a_CommandName .. "`";
+ return "`" .. a_CommandName .. "`"
end
- assert(type(a_CommandParams) == "table");
+ assert(type(a_CommandParams) == "table")
if ((a_CommandParams.Params == nil) or (a_CommandParams.Params == "")) then
- return "`" .. a_CommandName .. "`";
+ return "`" .. a_CommandName .. "`"
end
- assert(type(a_CommandParams.Params) == "string");
- return "`" .. a_CommandName .. " " .. a_CommandParams.Params .. "`";
+ assert(type(a_CommandParams.Params) == "string")
+ return "`" .. a_CommandName .. " " .. a_CommandParams.Params .. "`"
end
@@ -221,25 +221,25 @@ end
--- Writes the specified command detailed help array to the output file, in the forum dump format
local function WriteCommandParameterCombinationsForum(a_CmdString, a_ParameterCombinations, f)
- assert(type(a_CmdString) == "string");
- assert(type(a_ParameterCombinations) == "table");
- assert(f ~= nil);
+ assert(type(a_CmdString) == "string")
+ assert(type(a_ParameterCombinations) == "table")
+ assert(f ~= nil)
if (#a_ParameterCombinations == 0) then
-- No explicit parameter combinations to write
- return;
+ return
end
- f:write("The following parameter combinations are recognized:\n");
+ f:write("The following parameter combinations are recognized:\n")
for idx, combination in ipairs(a_ParameterCombinations) do
- f:write("[color=blue]", a_CmdString, "[/color] [color=green]", combination.Params or "", "[/color]");
+ f:write("[color=blue]", a_CmdString, "[/color] [color=green]", combination.Params or "", "[/color]")
if (combination.Help ~= nil) then
- f:write(" - ", ForumizeString(combination.Help));
+ f:write(" - ", ForumizeString(combination.Help))
end
if (combination.Permission ~= nil) then
- f:write(" (Requires permission '[color=red]", combination.Permission, "[/color]')");
+ f:write(" (Requires permission '[color=red]", combination.Permission, "[/color]')")
end
- f:write("\n");
+ f:write("\n")
end
end
@@ -249,25 +249,25 @@ end
--- Writes the specified command detailed help array to the output file, in the forum dump format
local function WriteCommandParameterCombinationsGithub(a_CmdString, a_ParameterCombinations, f)
- assert(type(a_CmdString) == "string");
- assert(type(a_ParameterCombinations) == "table");
- assert(f ~= nil);
+ assert(type(a_CmdString) == "string")
+ assert(type(a_ParameterCombinations) == "table")
+ assert(f ~= nil)
if (#a_ParameterCombinations == 0) then
-- No explicit parameter combinations to write
- return;
+ return
end
- f:write("The following parameter combinations are recognized:\n\n");
+ f:write("The following parameter combinations are recognized:\n\n")
for idx, combination in ipairs(a_ParameterCombinations) do
- f:write(GetCommandRefGithub(a_CmdString, combination));
+ f:write(GetCommandRefGithub(a_CmdString, combination))
if (combination.Help ~= nil) then
- f:write(" - ", GithubizeString(combination.Help));
+ f:write(" - ", GithubizeString(combination.Help))
end
if (combination.Permission ~= nil) then
- f:write(" (Requires permission '**", combination.Permission, "**')");
+ f:write(" (Requires permission '**", combination.Permission, "**')")
end
- f:write("\n");
+ f:write("\n")
end
end
@@ -278,29 +278,29 @@ end
--- Writes all commands in the specified category to the output file, in the forum dump format
local function WriteCommandsCategoryForum(a_Category, f)
-- Write category name:
- local CategoryName = a_Category.Name;
+ local CategoryName = a_Category.Name
if (CategoryName == "") then
- CategoryName = "General";
+ CategoryName = "General"
end
- f:write("\n[size=Large]", ForumizeString(a_Category.DisplayName or CategoryName), "[/size]\n");
+ f:write("\n[size=Large]", ForumizeString(a_Category.DisplayName or CategoryName), "[/size]\n")
-- Write description:
if (a_Category.Description ~= "") then
- f:write(ForumizeString(a_Category.Description), "\n");
+ f:write(ForumizeString(a_Category.Description), "\n")
end
-- Write commands:
- f:write("\n[list]");
+ f:write("\n[list]")
for idx2, cmd in ipairs(a_Category.Commands) do
- f:write("\n[b]", cmd.CommandString, "[/b] - ", ForumizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n");
+ f:write("\n[b]", cmd.CommandString, "[/b] - ", ForumizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n")
if (cmd.Info.Permission ~= nil) then
- f:write("Permission required: [color=red]", cmd.Info.Permission, "[/color]\n");
+ f:write("Permission required: [color=red]", cmd.Info.Permission, "[/color]\n")
end
if (cmd.Info.DetailedDescription ~= nil) then
- f:write(ForumizeString(cmd.Info.DetailedDescription));
+ f:write(ForumizeString(cmd.Info.DetailedDescription))
end
if (cmd.Info.ParameterCombinations ~= nil) then
- WriteCommandParameterCombinationsForum(cmd.CommandString, cmd.Info.ParameterCombinations, f);
+ WriteCommandParameterCombinationsForum(cmd.CommandString, cmd.Info.ParameterCombinations, f)
end
end
f:write("[/list]\n\n")
@@ -313,23 +313,23 @@ end
--- Writes all commands in the specified category to the output file, in the Github dump format
local function WriteCommandsCategoryGithub(a_Category, f)
-- Write category name:
- local CategoryName = a_Category.Name;
+ local CategoryName = a_Category.Name
if (CategoryName == "") then
- CategoryName = "General";
+ CategoryName = "General"
end
- f:write("\n### ", GithubizeString(a_Category.DisplayName or CategoryName), "\n");
+ f:write("\n### ", GithubizeString(a_Category.DisplayName or CategoryName), "\n")
-- Write description:
if (a_Category.Description ~= "") then
- f:write(GithubizeString(a_Category.Description), "\n\n");
+ f:write(GithubizeString(a_Category.Description), "\n\n")
end
- f:write("| Command | Permission | Description | \n")
- f:write("| ------- | ---------- | ----------- | \n")
+ f:write("| Command | Permission | Description |\n")
+ f:write("| ------- | ---------- | ----------- |\n")
-- Write commands:
for idx2, cmd in ipairs(a_Category.Commands) do
- f:write("|", cmd.CommandString, " | ", cmd.Info.Permission or "", " | ", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "| \n")
+ f:write("|", cmd.CommandString, " | ", cmd.Info.Permission or "", " | ", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "|\n")
end
f:write("\n\n")
end
@@ -340,24 +340,24 @@ end
local function DumpCommandsForum(a_PluginInfo, f)
-- Copy all Categories from a dictionary into an array:
- local Categories = BuildCategories(a_PluginInfo);
+ local Categories = BuildCategories(a_PluginInfo)
-- Sort the categories by name:
table.sort(Categories,
function(cat1, cat2)
- return (string.lower(cat1.Name) < string.lower(cat2.Name));
+ return (string.lower(cat1.Name) < string.lower(cat2.Name))
end
- );
+ )
if (#Categories == 0) then
- return;
+ return
end
- f:write("\n[size=X-Large]Commands[/size]\n");
+ f:write("\n[size=X-Large]Commands[/size]\n")
-- Dump per-category commands:
for idx, cat in ipairs(Categories) do
- WriteCommandsCategoryForum(cat, f);
+ WriteCommandsCategoryForum(cat, f)
end
end
@@ -367,24 +367,24 @@ end
local function DumpCommandsGithub(a_PluginInfo, f)
-- Copy all Categories from a dictionary into an array:
- local Categories = BuildCategories(a_PluginInfo);
+ local Categories = BuildCategories(a_PluginInfo)
-- Sort the categories by name:
table.sort(Categories,
function(cat1, cat2)
- return (string.lower(cat1.Name) < string.lower(cat2.Name));
+ return (string.lower(cat1.Name) < string.lower(cat2.Name))
end
- );
+ )
if (#Categories == 0) then
- return;
+ return
end
- f:write("\n# Commands\n");
+ f:write("\n# Commands\n")
-- Dump per-category commands:
for idx, cat in ipairs(Categories) do
- WriteCommandsCategoryGithub(cat, f);
+ WriteCommandsCategoryGithub(cat, f)
end
end
@@ -393,16 +393,16 @@ end
local function DumpAdditionalInfoForum(a_PluginInfo, f)
- local AInfo = a_PluginInfo.AdditionalInfo;
+ local AInfo = a_PluginInfo.AdditionalInfo
if (type(AInfo) ~= "table") then
-- There is no AdditionalInfo in a_PluginInfo
- return;
+ return
end
for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do
if ((info.Title ~= nil) and (info.Contents ~= nil)) then
- f:write("\n[size=X-Large]", ForumizeString(info.Title), "[/size]\n");
- f:write(ForumizeString(info.Contents), "\n");
+ f:write("\n[size=X-Large]", ForumizeString(info.Title), "[/size]\n")
+ f:write(ForumizeString(info.Contents), "\n")
end
end
end
@@ -412,16 +412,16 @@ end
local function DumpAdditionalInfoGithub(a_PluginInfo, f)
- local AInfo = a_PluginInfo.AdditionalInfo;
+ local AInfo = a_PluginInfo.AdditionalInfo
if (type(AInfo) ~= "table") then
-- There is no AdditionalInfo in a_PluginInfo
- return;
+ return
end
for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do
if ((info.Title ~= nil) and (info.Contents ~= nil)) then
- f:write("\n# ", GithubizeString(info.Title), "\n");
- f:write(GithubizeString(info.Contents), "\n");
+ f:write("\n# ", GithubizeString(info.Title), "\n")
+ f:write(GithubizeString(info.Contents), "\n")
end
end
end
@@ -434,53 +434,53 @@ end
-- Each array item is {Name = "PermissionName", Info = { PermissionInfo }}
local function BuildPermissions(a_PluginInfo)
-- Collect all used permissions from Commands, reference the commands that use the permission:
- local Permissions = a_PluginInfo.Permissions or {};
+ local Permissions = a_PluginInfo.Permissions or {}
local function CollectPermissions(a_CmdPrefix, a_Commands)
for cmd, info in pairs(a_Commands) do
- CommandString = a_CmdPrefix .. cmd;
+ CommandString = a_CmdPrefix .. cmd
if ((info.Permission ~= nil) and (info.Permission ~= "")) then
-- Add the permission to the list of permissions:
- local Permission = Permissions[info.Permission] or {};
- Permissions[info.Permission] = Permission;
+ local Permission = Permissions[info.Permission] or {}
+ Permissions[info.Permission] = Permission
-- Add the command to the list of commands using this permission:
- Permission.CommandsAffected = Permission.CommandsAffected or {};
- table.insert(Permission.CommandsAffected, CommandString);
+ Permission.CommandsAffected = Permission.CommandsAffected or {}
+ table.insert(Permission.CommandsAffected, CommandString)
end
-- Process the command param combinations for permissions:
- local ParamCombinations = info.ParameterCombinations or {};
+ local ParamCombinations = info.ParameterCombinations or {}
for idx, comb in ipairs(ParamCombinations) do
if ((comb.Permission ~= nil) and (comb.Permission ~= "")) then
-- Add the permission to the list of permissions:
- local Permission = Permissions[comb.Permission] or {};
- Permissions[info.Permission] = Permission;
+ local Permission = Permissions[comb.Permission] or {}
+ Permissions[info.Permission] = Permission
-- Add the command to the list of commands using this permission:
- Permission.CommandsAffected = Permission.CommandsAffected or {};
- table.insert(Permission.CommandsAffected, {Name = CommandString, Params = comb.Params});
+ Permission.CommandsAffected = Permission.CommandsAffected or {}
+ table.insert(Permission.CommandsAffected, {Name = CommandString, Params = comb.Params})
end
end
-- Process subcommands:
if (info.Subcommands ~= nil) then
- CollectPermissions(CommandString .. " ", info.Subcommands);
+ CollectPermissions(CommandString .. " ", info.Subcommands)
end
end
end
- CollectPermissions("", a_PluginInfo.Commands);
+ CollectPermissions("", a_PluginInfo.Commands)
-- Copy the list of permissions to an array:
- local PermArray = {};
+ local PermArray = {}
for name, perm in pairs(Permissions) do
- table.insert(PermArray, {Name = name, Info = perm});
+ table.insert(PermArray, {Name = name, Info = perm})
end
-- Sort the permissions array:
table.sort(PermArray,
function(p1, p2)
- return (p1.Name < p2.Name);
+ return (p1.Name < p2.Name)
end
- );
- return PermArray;
+ )
+ return PermArray
end
@@ -489,32 +489,32 @@ end
local function DumpPermissionsForum(a_PluginInfo, f)
-- Get the processed sorted array of permissions:
- local Permissions = BuildPermissions(a_PluginInfo);
+ local Permissions = BuildPermissions(a_PluginInfo)
if ((Permissions == nil) or (#Permissions <= 0)) then
- return;
+ return
end
-- Dump the permissions:
- f:write("\n[size=X-Large]Permissions[/size]\n[list]\n");
+ f:write("\n[size=X-Large]Permissions[/size]\n[list]\n")
for idx, perm in ipairs(Permissions) do
- f:write(" - [color=red]", perm.Name, "[/color] - ");
- f:write(ForumizeString(perm.Info.Description or ""));
- local CommandsAffected = perm.Info.CommandsAffected or {};
+ f:write(" - [color=red]", perm.Name, "[/color] - ")
+ f:write(ForumizeString(perm.Info.Description or ""))
+ local CommandsAffected = perm.Info.CommandsAffected or {}
if (#CommandsAffected > 0) then
- f:write("\n[list] Commands affected:\n- ");
- local Affects = {};
+ f:write("\n[list] Commands affected:\n- ")
+ local Affects = {}
for idx2, cmd in ipairs(CommandsAffected) do
- table.insert(Affects, GetCommandRefForum(cmd));
+ table.insert(Affects, GetCommandRefForum(cmd))
end
- f:write(table.concat(Affects, "\n - "));
- f:write("\n[/list]");
+ f:write(table.concat(Affects, "\n - "))
+ f:write("\n[/list]")
end
if (perm.Info.RecommendedGroups ~= nil) then
- f:write("\n[list] Recommended groups: ", perm.Info.RecommendedGroups, "[/list]");
+ f:write("\n[list] Recommended groups: ", perm.Info.RecommendedGroups, "[/list]")
end
- f:write("\n");
+ f:write("\n")
end
- f:write("[/list]");
+ f:write("[/list]")
end
@@ -523,34 +523,35 @@ end
local function DumpPermissionsGithub(a_PluginInfo, f)
-- Get the processed sorted array of permissions:
- local Permissions = BuildPermissions(a_PluginInfo);
+ local Permissions = BuildPermissions(a_PluginInfo)
if ((Permissions == nil) or (#Permissions <= 0)) then
- return;
+ return
end
-- Dump the permissions:
- f:write("\n# Permissions\n");
+ f:write("\n# Permissions\n")
f:write("| Permissions | Description | Commands | Recommended groups |\n")
f:write("| ----------- | ----------- | -------- | ------------------ |\n")
for idx, perm in ipairs(Permissions) do
- f:write(perm.Name, " | ");
- f:write(GithubizeString(perm.Info.Description or ""), " | ");
- local CommandsAffected = perm.Info.CommandsAffected or {};
+ f:write("| ", perm.Name, " | ")
+ f:write(GithubizeString(perm.Info.Description or ""), " | ")
+ local CommandsAffected = perm.Info.CommandsAffected or {}
if (#CommandsAffected > 0) then
- local Affects = {};
+ local Affects = {}
for idx2, cmd in ipairs(CommandsAffected) do
if (type(cmd) == "string") then
- table.insert(Affects, GetCommandRefGithub(cmd));
+ table.insert(Affects, GetCommandRefGithub(cmd))
else
- table.insert(Affects, GetCommandRefGithub(cmd.Name, cmd));
+ table.insert(Affects, GetCommandRefGithub(cmd.Name, cmd))
end
end
- f:write(table.concat(Affects, ", "), " | ");
+ f:write(table.concat(Affects, ", "))
end
+ f:write(" | ")
if (perm.Info.RecommendedGroups ~= nil) then
- f:write(perm.Info.RecommendedGroups, " |");
+ f:write(perm.Info.RecommendedGroups)
end
- f:write("\n");
+ f:write(" |\n")
end
end
@@ -558,45 +559,53 @@ end
+--- Dumps the forum-format info for the plugin
+-- Returns true on success, nil and error message on failure
local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo)
-- Open the output file:
- local f, msg = io.open(a_PluginInfo.Name .. "_forum.txt", "w");
+ local f, msg = io.open(a_PluginFolder .. "/forum_info.txt", "w")
if (f == nil) then
- print("\tCannot dump forum info for plugin " .. a_PluginFolder .. ": " .. msg);
- return;
+ return nil, msg
end
-- Write the description:
- f:write(ForumizeString(a_PluginInfo.Description), "\n");
- DumpAdditionalInfoForum(a_PluginInfo, f);
- DumpCommandsForum(a_PluginInfo, f);
- DumpPermissionsForum(a_PluginInfo, f);
+ f:write(ForumizeString(a_PluginInfo.Description), "\n")
+ DumpAdditionalInfoForum(a_PluginInfo, f)
+ DumpCommandsForum(a_PluginInfo, f)
+ DumpPermissionsForum(a_PluginInfo, f)
if (a_PluginInfo.SourceLocation ~= nil) then
- f:write("[b][color=blue]Source:[/color] [url=", a_PluginInfo.SourceLocation, "]Link[/url][/b]");
+ f:write("[b][color=blue]Source:[/color] [url=", a_PluginInfo.SourceLocation, "]Link[/url][/b]")
end
-
- f:close();
+ f:close()
+ return true
end
+--- Dumps the README.md file into the plugin's folder with the GitHub Markdown format
+-- Returns true on success, nil and error message on failure
local function DumpPluginInfoGithub(a_PluginFolder, a_PluginInfo)
+ -- Check the params:
+ assert(type(a_PluginFolder) == "string")
+ assert(type(a_PluginInfo) == "table")
+
-- Open the output file:
- local f, msg = io.open(a_PluginInfo.Name .. ".md", "w"); -- TODO: Save to a_PluginFolder .. "/Readme.md" instead
+ local f, msg = io.open(a_PluginFolder .. "/README.md", "w")
if (f == nil) then
- print("\tCannot dump github info for plugin " .. a_PluginFolder .. ": " .. msg);
- return;
+ print("\tCannot dump github info for plugin " .. a_PluginFolder .. ": " .. msg)
+ return nil, msg
end
-- Write the description:
- f:write(GithubizeString(a_PluginInfo.Description), "\n");
- DumpAdditionalInfoGithub(a_PluginInfo, f);
- DumpCommandsGithub(a_PluginInfo, f);
- DumpPermissionsGithub(a_PluginInfo, f);
+ f:write(GithubizeString(a_PluginInfo.Description), "\n")
+ DumpAdditionalInfoGithub(a_PluginInfo, f)
+ DumpCommandsGithub(a_PluginInfo, f)
+ DumpPermissionsGithub(a_PluginInfo, f)
- f:close();
+ f:close()
+ return true
end
@@ -607,36 +616,54 @@ end
-- Returns the g_PluginInfo table on success, or nil and error message on failure
local function LoadPluginInfo(a_FolderName)
-- Load and compile the Info file:
- local cfg, err = loadfile(a_FolderName .. "/Info.lua");
+ local cfg, err = loadfile(a_FolderName .. "/Info.lua")
if (cfg == nil) then
- return nil, "Cannot open 'Info.lua': " .. err;
+ return nil, "Cannot open 'Info.lua': " .. err
end
-- Execute the loaded file in a sandbox:
-- This is Lua-5.1-specific and won't work in Lua 5.2!
- local Sandbox = {};
- setfenv(cfg, Sandbox);
- cfg();
+ local Sandbox = {}
+ setfenv(cfg, Sandbox)
+ local isSuccess, errMsg = pcall(cfg)
+ if not(isSuccess) then
+ return nil, "Cannot load Info.lua: " .. (errMsg or "<unknown error>")
+ end
+
if (Sandbox.g_PluginInfo == nil) then
- return nil, "Info.lua doesn't contain the g_PluginInfo declaration";
+ return nil, "Info.lua doesn't contain the g_PluginInfo declaration"
end
- return Sandbox.g_PluginInfo;
+ return Sandbox.g_PluginInfo
end
+--- Processes the info for one plugin
+-- Returns true on success, nil and error message on failure
local function ProcessPluginFolder(a_FolderName)
- local PluginInfo, Msg = LoadPluginInfo(a_FolderName);
+ -- Load the plugin info:
+ local PluginInfo, Msg = LoadPluginInfo(a_FolderName)
if (PluginInfo == nil) then
- if (Msg ~= nil) then
- print("\t" .. Msg);
- end
- return;
+ return nil, "Cannot load info for plugin " .. a_FolderName .. ": " .. (Msg or "<unknown error>")
+ end
+
+ -- Dump the forum format:
+ local isSuccess
+ isSuccess, Msg = DumpPluginInfoForum(a_FolderName, PluginInfo)
+ if not(isSuccess) then
+ return nil, "Cannot dump forum info for plugin " .. a_FolderName .. ": " .. (Msg or "<unknown error>")
+ end
+
+ -- Dump the GitHub format:
+ isSuccess, Msg = DumpPluginInfoGithub(a_FolderName, PluginInfo)
+ if not(isSuccess) then
+ return nil, "Cannot dump GitHub info for plugin " .. a_FolderName .. ": " .. (Msg or "<unknown error>")
end
- DumpPluginInfoForum(a_FolderName, PluginInfo);
- DumpPluginInfoGithub(a_FolderName, PluginInfo);
+
+ -- All OK, return success
+ return true
end
@@ -650,7 +677,7 @@ local function LoadLFS()
function()
return require("lfs")
end
- );
+ )
-- ... rather, print a nice message with instructions:
if not(lfs) then
@@ -663,44 +690,50 @@ local function LoadLFS()
If you don't have luarocks installed, you need to install them using your OS's package manager, usually:
sudo apt-get install luarocks (Ubuntu / Debian)
On windows, a binary distribution can be downloaded from the LuaRocks homepage, http://luarocks.org/en/Download
- ]]);
+ ]])
- print("Original error text: ", err);
- return nil;
+ print("Original error text: ", err)
+ return nil
end
-- We now know that LFS is present, get it normally:
- return require("lfs");
+ return require("lfs")
end
-local Arg1 = ...;
+local Arg1 = arg[1]
if ((Arg1 ~= nil) and (Arg1 ~= "")) then
-- Called with a plugin folder name, export only that one
- ProcessPluginFolder(Arg1)
+ local isSuccess, msg = ProcessPluginFolder(Arg1)
+ if not(isSuccess) then
+ print(msg or "<unknown error>")
+ end
else
-- Called without any arguments, process all subfolders:
- local lfs = LoadLFS();
+ local lfs = LoadLFS()
if (lfs == nil) then
-- LFS not loaded, error has already been printed, just bail out
- return;
+ return
end
- print("Processing plugin subfolders:");
+ print("Processing plugin subfolders:")
for fnam in lfs.dir(".") do
if ((fnam ~= ".") and (fnam ~= "..")) then
- local Attributes = lfs.attributes(fnam);
+ local Attributes = lfs.attributes(fnam)
if (Attributes ~= nil) then
if (Attributes.mode == "directory") then
- print(fnam);
- ProcessPluginFolder(fnam);
+ print(fnam)
+ local isSuccess, msg = ProcessPluginFolder(fnam)
+ if not(isSuccess) then
+ print(" " .. (msg or "<unknown error>"))
+ end
end
end
end
end
end
-print("Done.");
+print("Done.")
diff --git a/MCServer/Plugins/MagicCarpet b/MCServer/Plugins/MagicCarpet
new file mode 160000
+Subproject 493f2dfa6d39f134e37c4c614cf8d6ffd10c825
diff --git a/MCServer/Plugins/MagicCarpet/objects.lua b/MCServer/Plugins/MagicCarpet/objects.lua
deleted file mode 100644
index 8d81623a5..000000000
--- a/MCServer/Plugins/MagicCarpet/objects.lua
+++ /dev/null
@@ -1,97 +0,0 @@
--- 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():GetDefaultWorld()
- 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():GetDefaultWorld()
- 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
deleted file mode 100644
index 417ea0e02..000000000
--- a/MCServer/Plugins/MagicCarpet/plugin.lua
+++ /dev/null
@@ -1,81 +0,0 @@
-local Carpets = {}
-local PLUGIN
-
-function Initialize( Plugin )
- Plugin:SetName( "MagicCarpet" )
- Plugin:SetVersion( 2 )
-
- cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)
- cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_DESTROYED, OnDisconnect)
-
- local PluginManager = cPluginManager:Get()
- PluginManager:BindCommand("/mc", "magiccarpet", HandleCarpetCommand, " - Spawns a magical carpet");
-
- PLUGIN = Plugin
-
- LOG( "Initialised " .. 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:SendMessageSuccess("You're on a magic carpet!")
- Player:SendMessageInfo("Look straight down to descend. Jump to ascend.")
- else
- Carpet:remove()
- Carpets[ Player ] = nil
- Player:SendMessageSuccess("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 OnPlayerMoving(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
- Player:TeleportToCoords(Player:GetPosX(), Carpet:getY() + 0.2, Player:GetPosZ())
- end
- Carpet:moveTo( cLocation:new( Player:GetPosX(), Player:GetPosY(), Player:GetPosZ() ) )
- end
-end
diff --git a/MCServer/Plugins/ProtectionAreas b/MCServer/Plugins/ProtectionAreas
-Subproject 7765048fa740b8f119db72a4ccc546504f86b2a
+Subproject 624580e5b522ba2799dfe5b5902b4002b1a8da3
diff --git a/MCServer/webadmin/(original).html b/MCServer/webadmin/(original).html
index 239a255e5..673a93ada 100644
--- a/MCServer/webadmin/(original).html
+++ b/MCServer/webadmin/(original).html
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<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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">
+<link rel="icon" href="files/favicon.ico">
<title>{TITLE}</title>
<style type="text/css" media="screen">
@@ -90,7 +90,7 @@
margin: 15px 0 10px 5px;
width: 180px;
height: 36px;
- background: url(data:image/png;base64,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) no-repeat left top;
+ background: url(files/logo.png) no-repeat left top;
}
h1 a {
@@ -114,7 +114,7 @@
#container {
- background: #fff url(data:image/gif;base64,R0lGODlhtAABAIAAAN3d3f///yH5BAAAAAAALAAAAAC0AAEAAAIMjI+py+0Po5y0WgYKADs%3D) repeat-y left top;
+ background: #fff url(files/background.gif) repeat-y left top;
border: 1px solid #ddd;
width: 918px;
@@ -155,7 +155,7 @@
margin-top:100px;
width: 180px;
height: 36px;
- background-image: url(data:image/png;base64,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);
+ background-image: url(files/logo.png);
}
#loginHolder {
diff --git a/MCServer/webadmin/files/guest.html b/MCServer/webadmin/files/guest.html
new file mode 100644
index 000000000..7ae78a3f0
--- /dev/null
+++ b/MCServer/webadmin/files/guest.html
@@ -0,0 +1,2 @@
+Hello! Welcome to the MCServer WebAdmin.<br>
+This is a default message, edit <b>files/guest.html</b> to add your own custom message.
diff --git a/MCServer/webadmin/files/header.png b/MCServer/webadmin/files/header.png
new file mode 100644
index 000000000..97b067715
--- /dev/null
+++ b/MCServer/webadmin/files/header.png
Binary files differ
diff --git a/MCServer/webadmin/files/home.gif b/MCServer/webadmin/files/home.gif
new file mode 100644
index 000000000..b10e0bed7
--- /dev/null
+++ b/MCServer/webadmin/files/home.gif
Binary files differ
diff --git a/MCServer/webadmin/files/loading.gif b/MCServer/webadmin/files/loading.gif
new file mode 100644
index 000000000..b8d06f669
--- /dev/null
+++ b/MCServer/webadmin/files/loading.gif
Binary files differ
diff --git a/MCServer/webadmin/files/log_out.png b/MCServer/webadmin/files/log_out.png
new file mode 100644
index 000000000..63232417a
--- /dev/null
+++ b/MCServer/webadmin/files/log_out.png
Binary files differ
diff --git a/MCServer/webadmin/files/login.css b/MCServer/webadmin/files/login.css
new file mode 100644
index 000000000..5d87da4c5
--- /dev/null
+++ b/MCServer/webadmin/files/login.css
@@ -0,0 +1,219 @@
+/* Copyright Justin S and MCServer Team, licensed under CC-BY-SA 3.0 */
+* {
+ margin: 0;
+}
+
+body {
+ font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
+ -webkit-font-smoothing: antialiased;
+ background: #fff url(header.png) repeat-x top left;
+ width: 100%;
+ min-width: 100%;
+ overflow: hidden;
+}
+
+a:link {
+ color: #555;
+ text-decoration: none;
+}
+
+a:visited {
+ color: #444;
+ text-decoration: none;
+}
+
+a:hover, a:active {
+ color: #000;
+ text-decoration: underline;
+}
+
+img {
+ border: none;
+}
+
+h1 {
+ color: #069;
+}
+
+.row1 {
+ border-bottom: 1px solid #000;
+ height: 100px;
+ max-height: 100px;
+}
+
+.row2 {
+ margin: 0 auto;
+ text-align: center;
+ vertical-align: middle;
+}
+
+.contention {
+ color: #000;
+ text-align: left;
+ line-height: 1.4;
+ margin: 0;
+ font-family: Tahoma,Verdana,Arial,Sans-Serif;
+ font-size: 13px;
+}
+
+button {
+ background: #fff;
+ color: #000;
+ border: 1px solid #ccc;
+ padding: 3px;
+ font-family: Tahoma,Verdana,Arial,Sans-Serif;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ margin: -3px 0;
+}
+
+button:hover {
+ border-top-color: #28597a;
+ background: #28597a;
+ color: #ccc;
+}
+
+button:active {
+ border-top-color: #1b435e;
+ background: #1b435e;
+}
+
+.push10 {
+ padding-bottom: 75px;
+}
+
+#panel .upper {
+ background: #dcdbdc url(tcat.png) repeat-x;
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #bbb;
+ padding: 7px;
+}
+
+#footer {
+ z-index: 99999;
+}
+
+#footer ul.menu {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+#footer ul.menu li {
+ margin: 0 5px;
+ display: inline;
+}
+
+#footer .upper {
+ background: #dcdbdc url(tcat.png) repeat-x;
+ border-top: 1px solid #bbb;
+ padding: 6px;
+ overflow: hidden;
+ font-size: 12px;
+}
+
+#footer .upper ul.bottom_links {
+ float: left;
+ margin: 3px 0 0 -5px;
+}
+
+#footer .lower {
+ background: #a1a2a2 url(thead.png) top left repeat-x;
+ color: #fff;
+ border-top: 1px solid #ccc;
+ border-bottom: 1px solid #ddd;
+ overflow: hidden;
+ padding: 8px;
+ font-size: 11px;
+}
+
+#footer .lower a:link, #footer .lower a:visited {
+ color: #fff;
+ font-weight: 700;
+}
+
+#footer .lower a:hover, #footer .lower a:active {
+ color: #fff;
+ font-weight: 700;
+}
+
+#footer .lower #current_time {
+ float: right;
+ padding-right: 6px;
+}
+
+.wrapper {
+ width: 85%;
+ min-width: 970px;
+ max-width: 1500px;
+ margin: auto;
+}
+
+#footer {
+ position: fixed;
+ left: 0;
+ bottom: 0;
+ height: 60px;
+ width: 100%;
+ background: #999;
+ border-top: 1px #000 solid;
+}
+
+* html #footer {
+ position: absolute;
+ top: expression((0-(footer.offsetHeight)+(document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight)+(ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop))+'px');
+}
+
+tr td.trow2:first-child {
+ border-left: 0;
+}
+
+tr td.trow2:last-child {
+ border-right: 0;
+}
+
+.tborder {
+ -moz-border-radius: 7px;
+ -webkit-border-radius: 7px;
+ border-radius: 7px;
+}
+
+.thead, .rounded_top {
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-topright: 6px;
+ -webkit-border-top-left-radius: 6px;
+ -webkit-border-top-right-radius: 6px;
+ border-top-left-radius: 6px;
+ border-top-right-radius: 6px;
+}
+
+table {
+ color: #000;
+ font-size: 13px;
+}
+
+.tborder {
+ background: #fff;
+ width: 100%;
+ margin: auto;
+ border: 1px solid #ccc;
+ padding: 1px;
+}
+
+.thead {
+ background: #a1a2a2 url(thead.png) top left repeat-x;
+ color: #fff;
+ border-bottom: 1px solid #8e8f8f;
+ padding: 8px;
+}
+
+.trow2 {
+ background: #efefef;
+ border: 1px solid;
+ border-color: #fff #ddd #ddd #fff;
+}
+
+.padtopp {
+ padding-top: 25px;
+}
diff --git a/MCServer/webadmin/files/login.gif b/MCServer/webadmin/files/login.gif
new file mode 100644
index 000000000..ce2cb6fc0
--- /dev/null
+++ b/MCServer/webadmin/files/login.gif
Binary files differ
diff --git a/MCServer/webadmin/files/logo_login.png b/MCServer/webadmin/files/logo_login.png
new file mode 100644
index 000000000..d2155f928
--- /dev/null
+++ b/MCServer/webadmin/files/logo_login.png
Binary files differ
diff --git a/MCServer/webadmin/files/pmfolder.gif b/MCServer/webadmin/files/pmfolder.gif
new file mode 100644
index 000000000..3fc68fdcb
--- /dev/null
+++ b/MCServer/webadmin/files/pmfolder.gif
Binary files differ
diff --git a/MCServer/webadmin/files/style.css b/MCServer/webadmin/files/style.css
index e7ffe3999..7c0671970 100644
--- a/MCServer/webadmin/files/style.css
+++ b/MCServer/webadmin/files/style.css
@@ -1,326 +1,427 @@
-/* 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;
+/* Copyright Justin S and MCServer Team, licensed under CC-BY-SA 3.0 */
+* {
+ margin: 0;
}
+
body {
- line-height: 1;
-}
-ol, ul {
- list-style: none;
-}
-blockquote, q {
- quotes: none;
+ font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
+ -webkit-font-smoothing: antialiased;
+ background: #fff;
+ width: 100%;
+ min-width: 100%;
+ height:100%;
+ min-height:100%;
+ overflow-y: scroll;
+ overflow-x: hidden;
}
-/* remember to define focus styles! */
-:focus {
- outline: 0;
+a:link {
+ color: #555;
+ text-decoration: none;
}
-/* remove textarea resize at Safari */
-textarea {
- resize: none;
+a:visited {
+ color: #444;
+ text-decoration: none;
}
-/* remember to highlight inserts somehow! */
-ins {
- text-decoration: none;
-}
-del {
- text-decoration: line-through;
+a:hover, a:active {
+ color: #000;
+ text-decoration: underline;
}
-/* tables still need 'cellspacing="0"' in the markup */
-table {
- border-collapse: collapse;
- border-spacing: 0;
+img {
+ border: none;
}
+h1 {
+ color: #069;
+ text-shadow: 2px 2px #000;
+}
-/*
- Origional from http://www.perspectived.com/
- Modified by Ben Phelps
- Made for FakeTruth - MCServer
-*/
+.row1 {
+ border-bottom: 1px #000 solid;
+ height: 100px;
+ max-height: 100px;
+ background: #fff url(header.png) repeat-x top left;
+}
-/* Basic ---------------------------------------- */
+.row2 {
+ margin: 0 auto;
+ text-align: center;
+ vertical-align: middle;
+ margin-top: 25px;
+ margin-bottom: 25px;
+}
-.clear { clear: both; }
+.contention {
+ color: #000;
+ text-align: left;
+ line-height: 1.4;
+ margin: 0;
+ font-family: Tahoma,Verdana,Arial,Sans-Serif;
+ font-size: 13px;
+ margin-bottom:75px;
+}
-body {
- background: white;
- font-family: Arial, Helvetica, sans-serif;
- font-size: 12px;
- color: #646464;
- text-align: center;
+.push25 {
}
-#wrapper {
- text-align: left;
- width: 930px;
- margin: 0 auto;
+#panel ul.menu {
+ margin: 0;
+ padding: 0;
+ list-style: none;
}
-/* Logo ---------------------------------------- */
+#panel ul.menu li {
+ margin: 0 5px;
+ display: inline;
+}
-h1 {
- margin: 15px 0 10px 5px;
- width: 180px;
- height: 36px;
- background: url(logo.png) no-repeat left top;
+#panel ul.menu li a {
+ padding-left: 20px;
+ background-repeat: no-repeat;
+ background-position: left center;
}
-h1 a {
- display: block;
- width: 225px;
- height: 28px;
+#panel .upper ul.top_links {
+ float: right;
+ font-weight: 700;
}
-h1 span { display: none; }
+#panel .upper {
+ background: #dcdbdc url(tcat.png) repeat-x;
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #bbb;
+ padding: 7px;
+}
-a {
- color: #646464;
+#footer ul.menu {
+ margin: 0;
+ padding: 0;
+ list-style: none;
}
-/* Container ---------------------------------------- */
+#footer ul.menu li {
+ margin: 0 5px;
+ display: inline;
+}
-#containerHolder {
- background: #eee;
- padding: 5px;
+#footer .upper {
+ background: #dcdbdc url(tcat.png) repeat-x;
+ border-top: 1px solid #bbb;
+ padding: 6px;
+ overflow: hidden;
+ font-size: 12px;
}
+#footer .upper ul.bottom_links {
+ float: left;
+ margin: 3px 0 0 -5px;
+}
-#container {
- background: #fff url(background.gif) repeat-y left top;
- border: 1px solid #ddd;
- width: 918px;
+#footer .lower {
+ background: #a1a2a2 url(thead.png) top left repeat-x;
+ color: #fff;
+ border-top: 1px solid #ccc;
+ border-bottom: 1px solid #ddd;
+ overflow: hidden;
+ padding: 8px;
+ font-size: 11px;
+}
+#footer .lower a:link,#footer .lower a:visited {
+ color: #fff;
+ font-weight: 700;
}
-#connectHolder {
- background: #eee;
- padding: 5px;
- margin-bottom:8px;
+#footer .lower a:hover,#footer .lower a:active {
+ color: #fff;
+ font-weight: 700;
}
+#footer .lower #current_time {
+ float: right;
+ padding-right: 6px;
+}
-#connect {
- border: 1px solid #ddd;
- background-color: #fff;
- padding:5px;
- width: 908px;
+.wrapper {
+ width: 85%;
+ min-width: 970px;
+ max-width: 1500px;
+ margin: auto;
}
-.pics {
- height: 375px;
- width: 600px;
-}
+#footer {
+ position: fixed;
+ left:0;
+ bottom:0;
+ height: 61px;
+ width: 100%;
+ background: #999;
+ border-top: 1px #000 solid;
+ border-bottom: 1px #000 solid;
+}
-.pics img {
- padding: 5px;
- border: 1px solid #ddd;
- background-color: #eee;
- width: 600px;
- height: 375px;
- margin-left: 15px;
+* html #footer {
+ position: absolute;
+ top: expression((0-(footer.offsetHeight)+(document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight)+(ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop))+'px');
}
-/* Login -------------------------------------- */
+tr td.trow1:first-child, tr td.trow2:first-child {
+ border-left: 0;
+}
-#loginLogo {
- margin: 0 auto;
- margin-top:100px;
- width: 180px;
- height: 36px;
- background-image: url(logo.png);
+tr td.trow1:last-child, tr td.trow2:last-child {
+ border-right: 0;
}
-#loginHolder {
- background: #eee;
- padding: 5px;
- width: 310px;
- margin: 0 auto;
- height: 90px;
- margin-top:20px;
+.tborder {
+ -moz-border-radius: 7px;
+ -webkit-border-radius: 7px;
+ border-radius: 7px;
}
-#login {
- padding:10px;
- width: 288px;
- height: 68px;
- border: 1px solid #ddd;
- background:#fff;
- text-align: left;
+.thead {
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-topright: 6px;
+ -webkit-border-top-left-radius: 6px;
+ -webkit-border-top-right-radius: 6px;
+ border-top-left-radius: 6px;
+ border-top-right-radius: 6px;
}
+table {
+ color: #000;
+ font-size: 13px;
+}
-/* Sidebar ---------------------------------------- */
+.tborder {
+ background: #fff;
+ width: 100%;
+ margin: auto;
+ border: 1px solid #ccc;
+ padding: 1px;
+}
-#sidebar {
- width: 179px;
- float: left;
+.thead {
+ background: #a1a2a2 url(thead.png) top left repeat-x;
+ color: #fff;
+ border-bottom: 1px solid #8e8f8f;
+ padding: 8px;
}
-#sidebar .sideNav { width: 179px; }
+.tcat {
+ background: #dcdbdc url(tcat.png) repeat-x;
+ color: #fff;
+ border-bottom: 1px solid #bbb;
+ padding: 6px;
+ font-size: 12px;
+}
-#sidebar .sideNav li { border-bottom: 1px solid #ddd; width: 179px; }
+.trow1 {
+ background: #f5f5f5;
+ border: 1px solid;
+ border-color: #fff #ddd #ddd #fff;
+}
-#sidebar .sideNav li a {
- display: block;
- color: #646464;
- background: #f6f6f6;
- text-decoration: none;
- height: 29px;
- line-height: 29px;
- padding: 0 19px;
- width: 141px;
+.trow2 {
+ background: #efefef;
+ border: 1px solid;
+ border-color: #fff #ddd #ddd #fff;
+ padding: 15px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
}
-#sidebar .sideNav li a:hover { background: #fdfcf6; }
+table {
+ color: #000;
+ font-size: 13px;
+ text-align: left;
+}
-#sidebar .sideNav li a.active, #sidebar .sideNav li a.active:hover {
- background: #f0f7fa;
- color: #c66653;
+.tborder {
+ background: #fff;
+ width: 100%;
+ margin: auto;
+ border: 1px solid #ccc;
+ padding: 1px;
}
-/* Breadcrumb ---------------------------------------- */
+.thead {
+ background: #a1a2a2 url(thead.png) top left repeat-x;
+ color: #fff;
+ border-bottom: 1px solid #8e8f8f;
+ padding: 8px;
+}
-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;
+.tcat {
+ background: #dcdbdc url(tcat.png) repeat-x;
+ color: #fff;
+ border-bottom: 1px solid #bbb;
+ padding: 6px;
+ font-size: 12px;
}
-h2 a {
- color: #646464;
- text-decoration: none;
+.trow1 {
+ background: #f5f5f5;
+ border: 1px solid;
+ border-color: #fff #ddd #ddd #fff;
}
-h2 a.active { color: #c66653; }
+.trow2 {
+ background: #efefef;
+ border: 1px solid;
+ border-color: #fff #ddd #ddd #fff;
+}
-h2 a:hover { text-decoration: underline; }
+.smalltext {
+ font-size: 11px;
+}
-/* Content ---------------------------------------- */
+textarea {
+ background: #fff;
+ color: #000;
+ border: 1px solid #ccc;
+ padding: 2px;
+ line-height: 1.4;
+ font-family: Tahoma,Verdana,Arial,Sans-Serif;
+ font-size: 13px;
+}
-#main {
- width: 700px;
- float: right;
- padding: 0 19px 0 0;
+select {
+ background: #fff;
+ padding: 3px;
+ border: 1px solid #ccc;
+ font-family: Tahoma,Verdana,Arial,Sans-Serif;
}
-#main p {
+.usercp_nav_item {
+ display: block;
+ padding: 1px 0 1px 23px;
+}
- padding: 10px;
+.usercp_nav_pmfolder {
+ background: url(pmfolder.gif) no-repeat left center;
+}
+.usercp_nav_sub_pmfolder {
+ padding-left: 40px;
+ background: url(sub_pmfolder.gif) no-repeat left center;
}
-h3 {
- font-size: 14px;
- line-height: 14px;
- font-weight: bold;
- color: #5494af;
- padding: 0 0 0 10px;
- margin: 20px 0 10px;
+.usercp_nav_home {
+ background: url(home.gif) no-repeat left center;
}
-h4 {
- padding: 0 0 0 10px;
- margin: 20px 0 10px;
+.pagehead {
+ top: 0;
+ left: 0;
+ width: 100%;
}
-#main ul {
- padding: 0 0 0 10px;
- list-style-type: circle;
- list-style-position: inside;
+table {
+ width: 100%;
}
-#main table {
- border-top: 1px solid #ddd;
- width: 700px;
+table th {
+ border-bottom: 1px solid rgba(0,0,0,0.12);
+ padding: 5px;
+ text-align: left;
}
-#main table tr th {
- text-align: left;
- background: #f6f6f6;
- padding: 0px 20px;
- height: 20px;
- line-height: 20px;
- border-bottom: 1px solid #ddd;
+table tr:nth-child(odd) {
+ background-color: rgba(0,0,0,0.015);
}
-#main table tr td {
- background: #f6f6f6;
- padding: 0px 20px;
- height: 29px;
- line-height: 29px;
- border-bottom: 1px solid #ddd;
+p {
+ margin: 4px 0;
+ padding: 4px 3px;
}
-#main table tr.odd td {
- background: #fbfbfb;
+a {
+ text-decoration: none;
+ color: #000;
+ -webkit-transition: color .1s linear;
+ -moz-transition: color .1s linear;
+ transition: color .1s linear;
}
-#main table tr:hover td { background: #fdfcf6; }
+a:hover {
+ color: #888;
+}
-#main table .action {
- text-align: right;
- padding: 0 20px 0 10px;
+input[type="text"] {
+ background: #fff;
+ color: #000;
+ border: 1px solid #ccc;
+ padding: 2px;
+ line-height: 1.4;
+ font-family: Tahoma,Verdana,Arial,Sans-Serif;
+ font-size: 13px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
}
-#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; }
+input[type="text"]:hover {
+ background-color: #E5E4E2;
+}
-#main table tr:hover .action a:hover { text-decoration: underline; }
+input[type="text"]:focus {
+ background-color: #E5E4E2;
+}
-fieldset {
- border: 1px solid #ddd;
- padding: 19px;
- margin: 0 0 20px 0;
- background: #fbfbfb;
+hr {
+ border: none;
+ height: 1px;
+ background-color: rgba(0,0,0,0.12);
}
-form p { margin: 0 0 14px 0; float: left; width: 100%; }
+h4 {
+ padding-bottom: 10px;
+ margin-bottom: 12px;
+ border-bottom: 1px solid rgba(0,0,0,0.12);
+}
-label {
- display: block;
- width: 100%;
- margin: 0 0 7px 0;
- line-height: 12px;
+#ChatDiv {
+ margin-bottom: 10px;
}
-/* Footer ---------------------------------------- */
+#ChatMessage {
+ width: 92%;
+ margin-right: 5px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+}
-#footer {
- margin: 10px 0 30px 0;
- font-size: 11px;
- line-height: 11px;
- color: #9B9B9B;
- padding: 0 0 0 5px;
+input[type="submit"] {
+ padding: 3px;
+ padding-left: 5px;
+ padding-right: 5px;
+ cursor: pointer;
+ font-family: Tahoma,Verdana,Arial,Sans-Serif;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ background: #f5f5f5;
+ border: 1px solid #ccc;
}
-#footer a { color: #9B9B9B; }
+input[type="submit"]:hover {
+ background-color: #E5E4E2;
+}
-#footer a:hover { text-decoration: none; }
+button:disabled,input:disabled {
+ padding: 3px;
+ padding-left: 5px;
+ padding-right: 5px;
+ cursor: pointer;
+ font-family: Tahoma,Verdana,Arial,Sans-Serif;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ border: none!important;
+ color: #fff!important;
+ background-color: #ccc!important;
+}
diff --git a/MCServer/webadmin/files/sub_pmfolder.gif b/MCServer/webadmin/files/sub_pmfolder.gif
new file mode 100644
index 000000000..3d0d6e627
--- /dev/null
+++ b/MCServer/webadmin/files/sub_pmfolder.gif
Binary files differ
diff --git a/MCServer/webadmin/files/tcat.png b/MCServer/webadmin/files/tcat.png
new file mode 100644
index 000000000..eb64eb3d6
--- /dev/null
+++ b/MCServer/webadmin/files/tcat.png
Binary files differ
diff --git a/MCServer/webadmin/files/thead.png b/MCServer/webadmin/files/thead.png
new file mode 100644
index 000000000..81aa04bac
--- /dev/null
+++ b/MCServer/webadmin/files/thead.png
Binary files differ
diff --git a/MCServer/webadmin/login_template.html b/MCServer/webadmin/login_template.html
index 913a85db0..7a8601065 100644
--- a/MCServer/webadmin/login_template.html
+++ b/MCServer/webadmin/login_template.html
@@ -1,25 +1,69 @@
+<!-- Copyright Justin S and MCServer Team, licensed under CC-BY-SA 3.0 */ -->
<html>
<head>
<title>MCServer WebAdmin - Login</title>
- <meta charset="UTF-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <link href="login.css" rel="stylesheet" type="text/css">
<link rel="icon" href="favicon.ico">
- <style type="text/css">
- header {
- margin: 0 auto;
- text-align: center;
- vertical-align: middle;
- }
- </style>
</head>
-
<body>
- <header>
- <img src="mc-logo.png" alt="MCServer Logo" class="logo">
- <h1>MCServer - WebAdmin</h1>
- <form method="get" action="webadmin/">
- <input type="submit" value="Log in">
- </form>
- </header>
+<div class="contention">
+ <div class="row1">
+ <div class="wrapper">
+ <img src="logo_login.png" alt="MCServer Logo" class="logo">
+ </div>
+ </div>
+ <div id="panel">
+ <div class="upper">
+ <div class="wrapper">
+ <div>
+ <form method="get" action="webadmin/" />
+ <button type="submit" value="Log in" style="width:150px;height:25px;font-family:'Source Sans Pro',sans-serif;background:transparent;border:none!important;vertical-align:middle">
+ <strong><img src="login.gif" style="vertical-align:bottom" /> WebAdmin Log in</strong>
+ </button>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row2 push10">
+ <div class="wrapper padtopp">
+ <table border="0" cellspacing="0" cellpadding="5" class="tborder" style="margin-bottom:5px">
+ <tbody>
+ <tr>
+ <td class="thead rounded_top">
+ <div style="float:left!important"><strong>MCServer WebAdmin</strong></div>
+ </td>
+ </tr>
+ <tr>
+ <td class="trow2 post_content">
+ <div class="post_body">
+ <iframe width="100%" height="100%" style="border:none;min-height:350px;max-height:450px" src="/guest.html"></iframe>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+<div id="footer">
+ <div class="upper">
+ <div class="wrapper">
+ <ul class="menu bottom_links">
+ <li><a href="http://www.mc-server.org" target="_blank">MCServer</a></li>
+ <li><a href="http://forum.mc-server.org" target="_blank">Forums</a></li>
+ <li><a href="http://builds.cuberite.org" target="_blank">Buildserver</a></li>
+ <li><a href="http://mc-server.xoft.cz/LuaAPI" target="_blank">API Documentation</a></li>
+ <li><a href="http://book.mc-server.org/" target="_blank">User's Manual</a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="lower">
+ <div class="wrapper">
+ <span id="copyright">Copyright © <a href="http://www.mc-server.org" target="_blank">MCServer Team</a> 2014.</span>
+ </div>
+ </div>
+</div>
</body>
-
</html>
diff --git a/MCServer/webadmin/template.html b/MCServer/webadmin/template.html
index 822f73857..b0864e35d 100644
--- a/MCServer/webadmin/template.html
+++ b/MCServer/webadmin/template.html
@@ -1,129 +1,140 @@
<!DOCTYPE html>
<html>
-<head>
- <title>{TITLE} | {PLUGIN_NAME}</title>
- <style type="text/css">
- body {
- line-height: 1;
- background: #B8B8B8;
- }
-
- #maincontent {
- padding: 0px 25px 10px 25px;
- }
-
- #wrapper {
- min-width: 850px;
- width: 75%;
- margin: 10px auto;
- background-color: white;
- border: 4px #888888 solid;
- border-radius: 10px;
- font-family: Calibri, Trebuchet MS;
- }
-
- header {
- text-align:center;
- padding: 10px; 0px;
- }
-
- span {
- text-align: right;
- float: right;
- border-left: 2px #C8C8C8 solid;
- border-bottom: 2px #C8C8C8 solid;
- padding: 2px 10px;
- }
-
- footer {
- font-family: helvetica;
- font-size: 10px;
- text-align: center;
- border-top: 1px #000 dotted;
- padding: 1px 0px 1px 0px;
- }
-
- table {
- border-collapse: collapse;
- border-spacing: 10;
- }
-
- table {
- border-top: 1px solid #ddd;
- width: 700px;
- }
-
- table tr th {
- text-align: left;
- background: #f6f6f6;
- padding: 0px 20px;
- height: 25px;
- line-height: 25px;
- border: 1px solid #ddd;
- border-radius: 3px;
- }
-
- table tr td {
- background: #f6f6f6;
- padding: 0px 20px;
- height: 29px;
- line-height: 29px;
- border: 1px solid #ddd;
- border-radius: 3px;
- }
- #main table tr.odd td {
- background: #fbfbfb;
- }
-
- table tr:hover td { background: #fdfcf6; }
- table .action {
- text-align: right;
- padding: 0 20px 0 10px;
- }
-
- table tr .action a { color: #9b9b9b; }
-
- #cssmenu{ height:10px; display:table; padding:0; margin: 0 auto; border:1px #707070 solid; border-radius:5px; }
- #cssmenu > ul {list-style:inside none; padding:0; margin:0;}
- #cssmenu > ul > li {list-style:inside none; padding:0; margin:0; float:left; display:block; position:relative;}
- #cssmenu > ul > li > a{ outline:none; display:block; position:relative; color:#E8E8E8; padding:10px 10px; font:bold 13px/100% Arial, Helvetica, sans-serif; text-align:center; text-decoration:none; text-shadow:1px 1px 0 rgba(0,0,0, 0.4); }
- #cssmenu > ul > li:first-child > a{border-radius:5px 0 0 5px;}
- /* #cssmenu > ul > li > a:after{ content:''; position:absolute; border-right:1px solid #FFFFFF; top:-1px; bottom:-1px; right:-2px; z-index:99; } */
- #cssmenu ul li.has-sub:hover > a:after{top:0; bottom:0;}
- #cssmenu > ul > li.has-sub > a:before{ content:''; position:absolute; top:18px; right:6px; border:5px solid transparent; border-top:5px solid #707070; }
- #cssmenu > ul > li.has-sub:hover > a:before{top:19px;}
- #cssmenu ul li.has-sub:hover > a{ background:#3f3f3f; border-color:#707070; padding-bottom:13px; padding-top:13px; top:-1px; z-index:999; }
- #cssmenu ul li.has-sub:hover > ul, #cssmenu ul li.has-sub:hover > div{display:block;}
- #cssmenu ul li.has-sub > a:hover{background:#3f3f3f; border-color:#3f3f3f;}
- #cssmenu ul li > ul, #cssmenu ul li > div{ display:none; width:auto; position:absolute; top:38px; padding:10px 0; background:#3f3f3f; border-radius:0 0 5px 5px; z-index:999; }
- #cssmenu ul li > ul{width:200px;}
- #cssmenu ul li > ul li{display:block; list-style:inside none; padding:0; margin:0; position:relative;}
- #cssmenu ul li > ul li a{ outline:none; display:block; position:relative; margin:0; padding:8px 20px; font:10pt Arial, Helvetica, sans-serif; color:#fff; text-decoration:none; text-shadow:1px 1px 0 rgba(0,0,0, 0.5); }
- #cssmenu, #cssmenu > ul > li > ul > li a:hover{ background:#C8C8C8;}
- #cssmenu > ul > li > a{border-right:1px solid #707070; color:#FFFFFF;}
- #cssmenu > ul > li > a:after{border-color:#707070;}
- #cssmenu > ul > li > a:hover{background:#B8B8B8;}
- </style>
- <meta name="msapplication-tooltip" content="MCServer WebAdministrator"/>
- <meta name="msapplication-navbutton-color" content="#B8B8B8" />
- <link rel="shortcut icon" href="http://mc-server.org/favicon.ico" />
-</head>
-
-<body>
- <div id="wrapper">
- <span><b>Login: {USERNAME}</b></span><br />
- <header>
- <img alt="" src="data:image/png;base64,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" />
- </header>
- <nav id="cssmenu">
- <ul>
- {MENU}
- </ul>
- </nav>
- <div id="maincontent">
- {CONTENT}
+ <head>
+ <title>{TITLE} | {PLUGIN_NAME}</title>
+ <style type="text/css">
+ body {
+ line-height: 1;
+ background: #B8B8B8;
+ }
+
+ #maincontent {
+ padding: 0px 25px 10px 25px;
+ }
+
+ #wrapper {
+ min-width: 850px;
+ width: 75%;
+ margin: 10px auto;
+ background-color: white;
+ border: 4px #888888 solid;
+ border-radius: 10px;
+ font-family: Calibri, Trebuchet MS;
+ }
+
+ header {
+ text-align:center;
+ padding: 10px; 0px;
+ }
+
+ span {
+ text-align: right;
+ float: right;
+ border-left: 2px #C8C8C8 solid;
+ border-bottom: 2px #C8C8C8 solid;
+ padding: 2px 10px;
+ }
+
+ footer {
+ font-family: helvetica;
+ font-size: 10px;
+ text-align: center;
+ border-top: 1px #000 dotted;
+ padding: 1px 0px 1px 0px;
+ }
+
+ table {
+ border-collapse: collapse;
+ border-spacing: 10;
+ }
+
+ table {
+ border-top: 1px solid #ddd;
+ width: 700px;
+ }
+
+ table tr th {
+ text-align: left;
+ background: #f6f6f6;
+ padding: 0px 20px;
+ height: 25px;
+ line-height: 25px;
+ border: 1px solid #ddd;
+ border-radius: 3px;
+ }
+
+ table tr td {
+ background: #f6f6f6;
+ padding: 0px 20px;
+ height: 29px;
+ line-height: 29px;
+ border: 1px solid #ddd;
+ border-radius: 3px;
+ }
+
+ #main table tr.odd td {
+ background: #fbfbfb;
+ }
+
+ table tr:hover td {
+ background: #fdfcf6;
+ }
+
+ table .action {
+ text-align: right;
+ padding: 0 20px 0 10px;
+ }
+
+ table tr .action a {
+ color: #9b9b9b;
+ }
+
+ #cssmenu{ height:10px; display:table; padding:0; margin: 0 auto; border:1px #707070 solid; border-radius:5px; }
+ #cssmenu > ul {list-style:inside none; padding:0; margin:0;}
+ #cssmenu > ul > li {list-style:inside none; padding:0; margin:0; float:left; display:block; position:relative;}
+ #cssmenu > ul > li > a{ outline:none; display:block; position:relative; color:#E8E8E8; padding:10px 10px; font:bold 13px/100% Arial, Helvetica, sans-serif; text-align:center; text-decoration:none; text-shadow:1px 1px 0 rgba(0,0,0, 0.4); }
+ #cssmenu > ul > li:first-child > a{border-radius:5px 0 0 5px;}
+ /* #cssmenu > ul > li > a:after{ content:''; position:absolute; border-right:1px solid #FFFFFF; top:-1px; bottom:-1px; right:-2px; z-index:99; } */
+ #cssmenu ul li.has-sub:hover > a:after{top:0; bottom:0;}
+ #cssmenu > ul > li.has-sub > a:before{ content:''; position:absolute; top:18px; right:6px; border:5px solid transparent; border-top:5px solid #707070; }
+ #cssmenu > ul > li.has-sub:hover > a:before{top:19px;}
+ #cssmenu ul li.has-sub:hover > a{ background:#3f3f3f; border-color:#707070; padding-bottom:13px; padding-top:13px; top:-1px; z-index:999; }
+ #cssmenu ul li.has-sub:hover > ul, #cssmenu ul li.has-sub:hover > div{display:block;}
+ #cssmenu ul li.has-sub > a:hover{background:#3f3f3f; border-color:#3f3f3f;}
+ #cssmenu ul li > ul, #cssmenu ul li > div{ display:none; width:auto; position:absolute; top:38px; padding:10px 0; background:#3f3f3f; border-radius:0 0 5px 5px; z-index:999; }
+ #cssmenu ul li > ul{width:200px;}
+ #cssmenu ul li > ul li{display:block; list-style:inside none; padding:0; margin:0; position:relative;}
+ #cssmenu ul li > ul li a{ outline:none; display:block; position:relative; margin:0; padding:8px 20px; font:10pt Arial, Helvetica, sans-serif; color:#fff; text-decoration:none; text-shadow:1px 1px 0 rgba(0,0,0, 0.5); }
+ #cssmenu, #cssmenu > ul > li > ul > li a:hover{ background:#C8C8C8;}
+ #cssmenu > ul > li > a { border-right:1px solid #707070; color:#FFFFFF; }
+ #cssmenu > ul > li > a:after { border-color:#707070; }
+ #cssmenu > ul > li > a:hover { background:#B8B8B8; }
+ </style>
+ <meta name="msapplication-tooltip" content="MCServer WebAdministrator"/>
+ <meta name="msapplication-navbutton-color" content="#B8B8B8" />
+ <link rel="shortcut icon" href="http://mc-server.org/favicon.ico" />
+ </head>
+ <body>
+ <div id="wrapper">
+ <span>
+ <b>Login: {USERNAME}</b>
+ </span>
+ <br />
+ <header>
+ <img alt="" src="files/logo.png" />
+ </header>
+ <nav id="cssmenu">
+ <ul>
+ {MENU}
+ </ul>
+ </nav>
+ <div id="maincontent">
+ {CONTENT}
+ </div>
+ <footer>
+ <p>MCServer is using {MEM}MB of memory, with {NUMCHUNKS} chunks loaded.</p>
+ <p>Web Design by <a href="https://github.com/WebFreak001"@WebFreak001</a></p>
+ </footer>
</div>
- <footer><p>MCServer is using {MEM}MB of memory, with {NUMCHUNKS} chunks loaded.</p><p>Web Design by Tiger</p></footer>
- </div>
-</head>
+ </body>
</html>
diff --git a/MCServer/webadmin/template.lua b/MCServer/webadmin/template.lua
index a7480f83e..4d3934da8 100644
--- a/MCServer/webadmin/template.lua
+++ b/MCServer/webadmin/template.lua
@@ -33,7 +33,7 @@ function GetDefaultPage()
local AllPlugins = PM:GetAllPlugins()
for key,value in pairs(AllPlugins) do
if( value ~= nil and value ~= false ) then
- Content = Content .. "<li>" .. key .. " V." .. value:GetVersion() .. "</li>"
+ Content = Content .. "<li>" .. key .. " (version " .. value:GetVersion() .. ")</li>"
end
end
@@ -70,25 +70,67 @@ function ShowPage(WebAdmin, TemplateRequest)
PageContent, SubTitle = GetDefaultPage()
end
+ local reqParamsClass = ""
+
+ for key,value in pairs(TemplateRequest.Request.Params) do
+ reqParamsClass = reqParamsClass .. " param-" .. string.lower(string.gsub(key, "[^a-zA-Z0-9]+", "-") .. "-" .. string.gsub(value, "[^a-zA-Z0-9]+", "-"))
+ end
+
+ if (string.gsub(reqParamsClass, "%s", "") == "") then
+ reqParamsClass = " no-param"
+ end
+
Output([[
-<!DOCTYPE html>
+<!-- Copyright Justin S and MCServer Team, licensed under CC-BY-SA 3.0 -->
+<html>
<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<link rel="icon" href="/favicon.ico">
-<title>]] .. Title .. [[</title>
-<link rel="stylesheet" type="text/css" media="screen" href="/style.css">
+ <title>]] .. Title .. [[</title>
+ <meta charset="UTF-8">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="/favicon.ico">
</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="]] .. BaseURL .. [["><span>MCServer</span></a>
- </h1>
- <div id="containerHolder">
- <div id="container">
- <div id="sidebar">
- <ul class="sideNav">
+<div class="contention push25">
+ <div class="pagehead">
+ <div class="row1">
+ <div class="wrapper">
+ <img src="/logo_login.png" alt="MCServer Logo" class="logo">
+ </div>
+ </div>
+ <div id="panel">
+ <div class="upper">
+ <div class="wrapper">
+ <ul class="menu top_links">
+ <li><a>Server Name: <strong>]] .. cRoot:Get():GetServer():GetServerID() .. [[</strong></a></li>
+ <li><a>Memory: <strong>]] .. MemoryUsageKiB / 1024 .. [[MB</strong></a></li>
+ <li><a>Chunks: <strong>]] .. NumChunks .. [[</strong></a></li>
+ </ul>
+ <div class="welcome"><strong>Welcome back, ]] .. TemplateRequest.Request.Username .. [[</strong>&nbsp;&nbsp;&nbsp;<a href=".././"><img src="/log_out.png" style="vertical-align:bottom;"> Log Out</a></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row2">
+ <div class="wrapper">
+ <table width="100%" border="0" align="center">
+ <tbody>
+ <tr>
+ <td width="180" valign="top">
+ <table border="0" cellspacing="0" cellpadding="5" class="tborder">
+ <tbody>
+ <tr>
+ <td class="thead"><strong>Menu</strong></td>
+ </tr>
+ <tr>
+ <td class="trow1 smalltext"><a href=']] .. BaseURL .. [[' class='usercp_nav_item usercp_nav_home'>Home</a></td>
+ </tr>
+ <tr>
+ <td class="tcat"><div><span class="smalltext"><strong><font color="#000">Server Management</font></strong></span></div></td>
+ </tr>
+ </tbody>
+ <tbody style="" id="usercppms_e">
+ <tr>
+ <td class="trow1 smalltext">
]])
@@ -97,41 +139,62 @@ function ShowPage(WebAdmin, TemplateRequest)
local PluginWebTitle = value:GetWebTitle()
local TabNames = value:GetTabNames()
if (GetTableSize(TabNames) > 0) then
- Output("<li>"..PluginWebTitle.."</li>\n");
+ Output("<div><a class='usercp_nav_item usercp_nav_pmfolder' style='text-decoration:none;'><b>"..PluginWebTitle.."</b></a></div>\n");
for webname,prettyname in pairs(TabNames) do
- Output("<li><a href='" .. BaseURL .. PluginWebTitle .. "/" .. webname .. "'>" .. prettyname .. "</a></li>\n")
+ Output("<div><a href='" .. BaseURL .. PluginWebTitle .. "/" .. webname .. "' class='usercp_nav_item usercp_nav_sub_pmfolder'>" .. prettyname .. "</a></div>\n")
end
+
+ Output("<br>\n");
end
end
Output([[
- </ul>
- <!-- // .sideNav -->
- </div>
- <!-- // #sidebar -->
- <!-- h2 stays for breadcrumbs -->
- <h2>Welcome ]] .. TemplateRequest.Request.Username .. [[</h2>
- <div id="main">
- <h3>]] .. SubTitle .. [[</h3>
- ]] .. PageContent .. [[
- </div>
- <!-- // #main -->
-
- <div class="clear"></div>
-
- </div>
- <!-- // #container -->
- </div>
- <!-- // #containerHolder -->
-
- <p id="footer">MCServer is using: ]] .. MemoryUsageKiB / 1024 .. [[ MiB of memory; Current chunk count: ]] .. NumChunks .. [[ </p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ <td valign="top" style='padding-left:25px;'>
+ <table border="0" cellspacing="0" cellpadding="5" class="tborder">
+ <tbody>
+ <tr>
+ <td class="thead" colspan="2"><strong>]] .. SubTitle .. [[</strong></td>
+ </tr>
+ <tr>
+ <td class="trow2">]] .. PageContent .. [[</td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+<div id="footer">
+ <div class="upper">
+ <div class="wrapper">
+ <ul class="menu bottom_links">
+ <li><a href="http://www.mc-server.org" target="_blank">MCServer</a></li>
+ <li><a href="http://forum.mc-server.org" target="_blank">Forums</a></li>
+ <li><a href="http://builds.cuberite.org" target="_blank">Buildserver</a></li>
+ <li><a href="http://mc-server.xoft.cz/LuaAPI" target="_blank">API Documentation</a></li>
+ <li><a href="http://book.mc-server.org/" target="_blank">User's Manual</a></li>
+ </ul>
+ </div>
</div>
- <!-- // #wrapper -->
+ <div class="lower">
+ <div class="wrapper">
+ <span id="copyright">Copyright © <a href="http://www.mc-server.org" target="_blank">MCServer Team</a> 2014.</span>
+ </div>
+ </div>
+</div>
+</div>
</body>
</html>
- ]])
+]])
return table.concat(SiteContent)
end
diff --git a/MCServer/webadmin/template_orig.lua b/MCServer/webadmin/template_orig.lua
new file mode 100644
index 000000000..a7480f83e
--- /dev/null
+++ b/MCServer/webadmin/template_orig.lua
@@ -0,0 +1,137 @@
+-- Use a table for fast concatenation of strings
+local SiteContent = {}
+function Output(String)
+ table.insert(SiteContent, String)
+end
+
+
+
+
+
+function GetTableSize(Table)
+ local Size = 0
+ for key,value in pairs(Table) do
+ Size = Size + 1
+ end
+ return Size
+end
+
+
+
+
+
+function GetDefaultPage()
+ local PM = cRoot:Get():GetPluginManager()
+
+ local SubTitle = "Current Game"
+ local Content = ""
+
+ Content = Content .. "<h4>Server Name:</h4>"
+ Content = Content .. "<p>" .. cRoot:Get():GetServer():GetServerID() .. "</p>"
+
+ Content = Content .. "<h4>Plugins:</h4><ul>"
+ local AllPlugins = PM:GetAllPlugins()
+ for key,value in pairs(AllPlugins) do
+ if( value ~= nil and value ~= false ) then
+ Content = Content .. "<li>" .. key .. " V." .. value:GetVersion() .. "</li>"
+ end
+ end
+
+ Content = Content .. "</ul>"
+ Content = Content .. "<h4>Players:</h4><ul>"
+
+ local AddPlayerToTable = function( Player )
+ Content = Content .. "<li>" .. Player:GetName() .. "</li>"
+ end
+ cRoot:Get():ForEachPlayer( AddPlayerToTable )
+
+ Content = Content .. "</ul><br>";
+
+ return Content, SubTitle
+end
+
+
+
+
+
+function ShowPage(WebAdmin, TemplateRequest)
+ SiteContent = {}
+ local BaseURL = WebAdmin:GetBaseURL(TemplateRequest.Request.Path)
+ local Title = "MCServer WebAdmin"
+ local MemoryUsageKiB = cRoot:GetPhysicalRAMUsage()
+ local NumChunks = cRoot:Get():GetTotalChunkCount()
+ local PluginPage = WebAdmin:GetPage(TemplateRequest.Request)
+ local PageContent = PluginPage.Content
+ local SubTitle = PluginPage.PluginName
+ if (PluginPage.TabName ~= "") then
+ SubTitle = PluginPage.PluginName .. " - " .. PluginPage.TabName
+ end
+ if (PageContent == "") then
+ PageContent, SubTitle = GetDefaultPage()
+ end
+
+ Output([[
+<!DOCTYPE html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="icon" href="/favicon.ico">
+<title>]] .. Title .. [[</title>
+<link rel="stylesheet" type="text/css" media="screen" href="/style.css">
+</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="]] .. BaseURL .. [["><span>MCServer</span></a>
+ </h1>
+ <div id="containerHolder">
+ <div id="container">
+ <div id="sidebar">
+ <ul class="sideNav">
+ ]])
+
+
+ local AllPlugins = WebAdmin:GetPlugins()
+ for key,value in pairs(AllPlugins) do
+ local PluginWebTitle = value:GetWebTitle()
+ local TabNames = value:GetTabNames()
+ if (GetTableSize(TabNames) > 0) then
+ Output("<li>"..PluginWebTitle.."</li>\n");
+
+ for webname,prettyname in pairs(TabNames) do
+ Output("<li><a href='" .. BaseURL .. PluginWebTitle .. "/" .. webname .. "'>" .. prettyname .. "</a></li>\n")
+ end
+ end
+ end
+
+
+ Output([[
+ </ul>
+ <!-- // .sideNav -->
+ </div>
+ <!-- // #sidebar -->
+ <!-- h2 stays for breadcrumbs -->
+ <h2>Welcome ]] .. TemplateRequest.Request.Username .. [[</h2>
+ <div id="main">
+ <h3>]] .. SubTitle .. [[</h3>
+ ]] .. PageContent .. [[
+ </div>
+ <!-- // #main -->
+
+ <div class="clear"></div>
+
+ </div>
+ <!-- // #container -->
+ </div>
+ <!-- // #containerHolder -->
+
+ <p id="footer">MCServer is using: ]] .. MemoryUsageKiB / 1024 .. [[ MiB of memory; Current chunk count: ]] .. NumChunks .. [[ </p>
+ </div>
+ <!-- // #wrapper -->
+</body>
+</html>
+ ]])
+
+ return table.concat(SiteContent)
+end