ProtectionAreas: Implemented all command handlers.
They still call unimplemented methods in the DB, and haven't been properly tested git-svn-id: http://mc-server.googlecode.com/svn/trunk@1561 0a769ca7-a7f5-676a-18bf-c427514a06d6master
parent
6cb76856ff
commit
9790a6817c
|
@ -33,15 +33,6 @@ function HandleAddArea(a_Split, a_Player)
|
|||
end
|
||||
local Cuboid = CmdState:GetCurrentCuboid();
|
||||
if (Cuboid == nil) then
|
||||
a_Player:SendMessage("Cannot add area, internal plugin error (Cuboid == nil)");
|
||||
return true;
|
||||
end
|
||||
|
||||
-- If the cuboid hasn't been assigned, give the player an error message and bail out
|
||||
if (
|
||||
(Cuboid.p1.x == 0) and (Cuboid.p1.y == 0) and (Cuboid.p1.z == 0) and
|
||||
(Cuboid.p1.x == 0) and (Cuboid.p1.y == 0) and (Cuboid.p1.z == 0)
|
||||
) then
|
||||
a_Player:SendMessage("Cannot add area, no area has been selected. Use a ProtWand lclk / rclk to select area first");
|
||||
return true;
|
||||
end
|
||||
|
@ -53,10 +44,11 @@ function HandleAddArea(a_Split, a_Player)
|
|||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
g_Storage:AddArea(Cuboid, a_Player:GetName(), AllowedNames);
|
||||
g_Storage:AddArea(Cuboid, a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames);
|
||||
a_Player:SendMessage("Area added");
|
||||
|
||||
-- TODO: Reload all currently logged in players
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
@ -66,7 +58,36 @@ end
|
|||
|
||||
|
||||
function HandleAddAreaCoords(a_Split, a_Player)
|
||||
-- TODO
|
||||
-- Command syntax: ProtAddCoords x1 z1 x2 z2 username1 [username2] [username3] ...
|
||||
if (#a_Split < 6) then
|
||||
a_Player:SendMessage("Not enough parameters. Expected <x1> <z1> <x2> <z2> coords and a list of usernames.");
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Convert the coords to a cCuboid
|
||||
local x1, z1 = tonumber(a_Split[2]), tonumber(a_Split[3]);
|
||||
local x2, z2 = tonumber(a_Split[4]), tonumber(a_Split[5]);
|
||||
if ((x1 == nil) or (z1 == nil) or (x2 == nil) or (z2 == nil)) then
|
||||
a_Player:SendMessage("Cannot parse coords.");
|
||||
return true;
|
||||
end
|
||||
local Cuboid = cCuboid(x1, 0, z1, x2, 255, z1);
|
||||
Cuboid:Sort();
|
||||
|
||||
-- Put all allowed players into a table:
|
||||
AllowedNames = {};
|
||||
for i = 6, #a_Split do
|
||||
table.insert(AllowedNames, a_Split[i]);
|
||||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
g_Storage:AddArea(Cuboid, a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames);
|
||||
a_Player:SendMessage("Area added");
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
@ -74,7 +95,26 @@ end
|
|||
|
||||
|
||||
function HandleAddAreaUser(a_Split, a_Player)
|
||||
-- TODO
|
||||
-- Command syntax: ProtAddUser AreaID username1 [username2] [username3] ...
|
||||
if (#a_Split < 3) then
|
||||
a_Player:SendMessage("Not enough parameters. Expected <AreaID> and a list of usernames.");
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Put all allowed players into a table:
|
||||
AllowedNames = {};
|
||||
for i = 3, #a_Split do
|
||||
table.insert(AllowedNames, a_Split[i]);
|
||||
end
|
||||
|
||||
-- Add the area to the storage
|
||||
g_Storage:AddAreaUsers(tonumber(a_Split[2]), a_Player:GetWorld():GetName(), a_Player:GetName(), AllowedNames);
|
||||
a_Player:SendMessage("Users added: " .. table.concat(AllowedNames, ", "));
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
@ -82,7 +122,26 @@ end
|
|||
|
||||
|
||||
function HandleDelArea(a_Split, a_Player)
|
||||
-- TODO
|
||||
-- Command syntax: ProtDelArea AreaID
|
||||
if (#a_Split ~= 2) then
|
||||
a_Player:SendMessage("Parameter mismatch. Expected <AreaID>.");
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Parse the AreaID
|
||||
local AreaID = tonumber(a_Split[2]);
|
||||
if (AreaID == nil) then
|
||||
a_Player:SendMessage("Cannot parse <AreaID>.");
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Delete the area
|
||||
g_Storage:DelArea(a_Player:GetWorld():GetName(), AreaID);
|
||||
|
||||
-- Reload all currently logged in players
|
||||
ReloadAllPlayersInWorld(a_Player:GetWorld():GetName());
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
@ -104,7 +163,61 @@ end
|
|||
|
||||
|
||||
function HandleListAreas(a_Split, a_Player)
|
||||
-- TODO
|
||||
-- Command syntax: ProtListAreas [x, z]
|
||||
|
||||
local x, z;
|
||||
if (#a_Split == 1) then
|
||||
-- Get the last "wanded" coord
|
||||
local CmdState = GetCommandStateForPlayer(a_Player);
|
||||
if (CmdState == nil) then
|
||||
a_Player:SendMessage("Cannot list area, internal plugin error (CmdState == nil)");
|
||||
return true;
|
||||
end
|
||||
x, z = CmdState:GetLastCoords();
|
||||
if ((x == nil) or (z == nil)) then
|
||||
a_Player:SendMessage("Cannot list areas, no query point has been selected. Use a ProtWand lclk / rclk to select a point first");
|
||||
return true;
|
||||
end
|
||||
elseif (#a_Split == 3) then
|
||||
-- Parse the coords from the command params
|
||||
x = tonumber(a_Split[2]);
|
||||
z = tonumber(a_Split[3]);
|
||||
if ((x == nil) or (z == nil)) then
|
||||
a_Player:SendMessage("Cannot list areas, cannot parse coords in params");
|
||||
return true;
|
||||
end
|
||||
else
|
||||
-- Wrong number of params, report back to the user
|
||||
a_Player:SendMessage("Cannot list areas, syntax error. Expected either no params or <x> <z>.");
|
||||
return true;
|
||||
end
|
||||
|
||||
a_Player:SendMessage("Listing protection areas intersecting block column {" .. x .. ", " .. z .. "}:");
|
||||
|
||||
-- List areas intersecting the coords
|
||||
local Areas = g_PlayerAreas[a_Player:GetUniqueID()]
|
||||
Areas:ForEachArea(
|
||||
function(a_Cuboid, a_IsAllowed)
|
||||
if (not(a_Cuboid:IsInside(x, 1, z))) then
|
||||
-- This cuboid doesn't intersect the column
|
||||
return;
|
||||
end
|
||||
-- Column intersected, send to the player
|
||||
local Coords = "{" ..
|
||||
a_Cuboid.p1.x .. ", " .. a_Cuboid.p1.z .. "} - {" ..
|
||||
a_Cuboid.p2.x .. ", " .. a_Cuboid.p2.z .. "} ";
|
||||
local Allowance;
|
||||
if (a_IsAllowed) then
|
||||
Allowance = "Allowed";
|
||||
else
|
||||
Allowance = "NOT allowed";
|
||||
end
|
||||
a_Player:SendMessage(" " .. Coords .. Allowance);
|
||||
end
|
||||
);
|
||||
|
||||
a_Player:SendMessage("Area list finished");
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
@ -112,7 +225,22 @@ end
|
|||
|
||||
|
||||
function HandleRemoveUser(a_Split, a_Player)
|
||||
-- TODO
|
||||
-- Command syntax: ProtRemUser AreaID UserName
|
||||
if (#a_Split ~= 3) then
|
||||
a_Player:SendMessage("Parameter mismatch. Expected <AreaID> <UserName>.");
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Parse the AreaID
|
||||
local AreaID = tonumber(a_Split[2]);
|
||||
if (AreaID == nil) then
|
||||
a_Player:SendMessage("Cannot parse <AreaID>.");
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Remove the user from the DB
|
||||
g_Storage:RemoveUser(AreaID, a_Split[3], a_Player:GetWorld():GetName());
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
@ -120,7 +248,15 @@ end
|
|||
|
||||
|
||||
function HandleRemoveUserAll(a_Split, a_Player)
|
||||
-- TODO
|
||||
-- Command syntax: ProtRemUserAll UserName
|
||||
if (#a_Split ~= 2) then
|
||||
a_Player:SendMessage("Parameter mismatch. Expected <UserName>.");
|
||||
return true;
|
||||
end
|
||||
|
||||
-- Remove the user from the DB
|
||||
g_Storage.RemoveUserAll(a_Split[2], a_Player:GetWorld():GetName());
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -18,8 +18,10 @@ Also, a global table g_CommandStates is the map of PlayerEntityID -> cCommandSta
|
|||
|
||||
cCommandState = {
|
||||
-- Default coords
|
||||
m_Coords1 = {x = 0, y = 0, z = 0};
|
||||
m_Coords2 = {x = 0, y = 0, z = 0};
|
||||
m_Coords1 = {x = 0, z = 0}; -- lclk coords
|
||||
m_Coords2 = {x = 0, z = 0}; -- rclk coords
|
||||
m_LastCoords = 0; -- When Coords1 or Coords2 is set, this gets set to 1 or 2, signifying the last changed set of coords
|
||||
m_HasCoords = 1; -- Set to 0, 1, 2 or 3, based on which set of coords has been set (bitmask)
|
||||
};
|
||||
|
||||
g_CommandStates = {};
|
||||
|
@ -41,6 +43,11 @@ end
|
|||
|
||||
--- Returns the current coord pair as a cCuboid object
|
||||
function cCommandState:GetCurrentCuboid()
|
||||
if (self.m_HasCoords ~= 3) then
|
||||
-- Some of the coords haven't been set yet
|
||||
return nil;
|
||||
end
|
||||
|
||||
local res = cCuboid(
|
||||
self.m_Coords1.x, self.m_Coords1.y, self.m_Coords1.z,
|
||||
self.m_Coords2.x, self.m_Coords2.y, self.m_Coords2.z
|
||||
|
@ -52,11 +59,33 @@ end
|
|||
|
||||
|
||||
|
||||
|
||||
--- Returns the x, z coords that were the set last,
|
||||
-- That is, either m_Coords1 or m_Coords2, based on m_LastCoords member
|
||||
-- Returns nothing if no coords were set yet
|
||||
function cCommandState:GetLastCoords()
|
||||
if (self.m_LastCoords == 0) then
|
||||
-- No coords have been set yet
|
||||
return;
|
||||
elseif (self.m_LastCoords == 1) then
|
||||
return self.m_Coords1.x, self.m_Coords1.z;
|
||||
elseif (self.m_LastCoords == 2) then
|
||||
return self.m_Coords2.x, self.m_Coords2.z;
|
||||
else
|
||||
LOGWARNING(PluginPrefix .. "cCommandState is in an unexpected state, m_LastCoords == " .. self.m_LastCoords);
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Sets the first set of coords (upon rclk with a wand)
|
||||
function cCommandState:SetCoords1(a_BlockX, a_BlockY, a_BlockZ)
|
||||
function cCommandState:SetCoords1(a_BlockX, a_BlockZ)
|
||||
self.m_Coords1.x = a_BlockX;
|
||||
self.m_Coords1.y = a_BlockY;
|
||||
self.m_Coords1.z = a_BlockZ;
|
||||
self.m_LastCoords = 1;
|
||||
end
|
||||
|
||||
|
||||
|
@ -64,10 +93,10 @@ end
|
|||
|
||||
|
||||
--- Sets the second set of coords (upon lclk with a wand)
|
||||
function cCommandState:SetCoords2(a_BlockX, a_BlockY, a_BlockZ)
|
||||
function cCommandState:SetCoords2(a_BlockX, a_BlockZ)
|
||||
self.m_Coords2.x = a_BlockX;
|
||||
self.m_Coords2.y = a_BlockY;
|
||||
self.m_Coords2.z = a_BlockZ;
|
||||
self.m_LastCoords = 2;
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -35,10 +35,8 @@ end;
|
|||
|
||||
function OnPlayerJoined(a_Player)
|
||||
-- Create a new cPlayerAreas object for this player
|
||||
local PlayerName = a_Player:GetName();
|
||||
local PlayerID = a_Player:GetUniqueID();
|
||||
if (g_PlayerAreas[PlayerID] == nil) then
|
||||
g_PlayerAreas[PlayerID] = g_Storage:LoadPlayerAreas(PlayerName);
|
||||
if (g_PlayerAreas[a_Player:GetUniqueID()] == nil) then
|
||||
LoadPlayerAreas(a_Player);
|
||||
end;
|
||||
|
||||
return false;
|
||||
|
@ -60,8 +58,8 @@ function OnPlayerLeftClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace,
|
|||
a_BlockX, a_BlockY, a_BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
-- Set the coords in the CommandState
|
||||
GetCommandStateForPlayer(a_Player):SetCoords1(a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_Player:SendMessage("Coords1 set as {" .. a_BlockX .. ", " .. a_BlockY .. ", " .. a_BlockZ .."}.");
|
||||
GetCommandStateForPlayer(a_Player):SetCoords1(a_BlockX, a_BlockZ);
|
||||
a_Player:SendMessage("Coords1 set as {" .. a_BlockX .. ", " .. a_BlockZ .."}.");
|
||||
return true;
|
||||
end;
|
||||
|
||||
|
@ -91,14 +89,14 @@ function OnPlayerRightClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace,
|
|||
a_BlockX, a_BlockY, a_BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
-- Set the coords in the CommandState
|
||||
GetCommandStateForPlayer(a_Player):SetCoords2(a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_Player:SendMessage("Coords2 set as {" .. a_BlockX .. ", " .. a_BlockY .. ", " .. a_BlockZ .."}.");
|
||||
GetCommandStateForPlayer(a_Player):SetCoords2(a_BlockX, a_BlockZ);
|
||||
a_Player:SendMessage("Coords2 set as {" .. a_BlockX .. ", " .. a_BlockZ .."}.");
|
||||
return true;
|
||||
end;
|
||||
|
||||
-- Check the player areas to see whether to disable this action
|
||||
local Areas = g_PlayerAreas[a_Player:GetUniqueID()];
|
||||
if not(Areas:CanInteractWithBlock(a_BlockX, a_BlockY, a_BlockZ)) then
|
||||
if not(Areas:CanInteractWithBlock(a_BlockX, a_BlockZ)) then
|
||||
return true;
|
||||
end
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ end
|
|||
|
||||
-- Adds a new cuboid to the area list, where the player is either allowed or not, depending on the IsAllowed param
|
||||
function cPlayerAreas:AddArea(a_Cuboid, a_IsAllowed)
|
||||
table.insert(self, {Cuboid = a_Cuboid, IsAllowed = a_IsAllowed});
|
||||
table.insert(self, {m_Cuboid = a_Cuboid, m_IsAllowed = a_IsAllowed});
|
||||
end
|
||||
|
||||
|
||||
|
@ -45,12 +45,12 @@ end
|
|||
|
||||
|
||||
--- returns true if the player owning this object can interact with the specified block
|
||||
function cPlayerAreas:CanInteractWithBlock(a_BlockX, a_BlockY, a_BlockZ)
|
||||
function cPlayerAreas:CanInteractWithBlock(a_BlockX, a_BlockZ)
|
||||
-- iterate through all the stored areas:
|
||||
local IsInsideAnyArea = false;
|
||||
for idx, Area in ipairs(self) do
|
||||
if (Area.Cuboid:IsInside(a_BlockX, a_BlockY, a_BlockZ)) then
|
||||
if (Area.IsAllowed) then
|
||||
if (Area.m_Cuboid:IsInside(a_BlockX, 1, a_BlockZ)) then -- We don't care about Y coords, so use a dummy value
|
||||
if (Area.m_IsAllowed) then
|
||||
return true;
|
||||
end
|
||||
-- The coords are inside a cuboid for which the player doesn't have access, take a note of it
|
||||
|
@ -71,3 +71,19 @@ end
|
|||
|
||||
|
||||
|
||||
|
||||
--- Calls the specified callback for each area contained within
|
||||
-- a_Callback has a signature: function(a_Cuboid, a_IsAllowed)
|
||||
-- Returns true if all areas have been enumerated, false if the callback has aborted by returning true
|
||||
function cPlayerAreas:ForEachArea(a_Callback)
|
||||
for idx, Area in ipairs(self) do
|
||||
if (a_Callback(Area.m_Cuboid, Area.m_IsAllowed)) then
|
||||
return false;
|
||||
end
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
-- ProtectionAreas.lua
|
||||
-- Defines the main plugin entrypoint
|
||||
-- Defines the main plugin entrypoint, as well as some utility functions
|
||||
|
||||
|
||||
|
||||
|
@ -26,8 +26,38 @@ function Initialize(a_Plugin)
|
|||
InitializeHooks(a_Plugin);
|
||||
InitializeCommandHandlers();
|
||||
|
||||
-- TODO: We might be reloading, so there may be players already present in the server
|
||||
-- Reload areas for all present players
|
||||
-- We might be reloading, so there may be players already present in the server; reload all of them
|
||||
local function ReloadPlayers(a_World)
|
||||
ReloadAllPlayersInWorld(a_World:GetName());
|
||||
end
|
||||
cRoot:Get():ForEachWorld(ReloadPlayers);
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Loads a cPlayerAreas object from the DB for the player, and assigns it to the player map
|
||||
function LoadPlayerAreas(a_Player)
|
||||
local PlayerID = a_Player:GetUniqueID();
|
||||
local PlayerX = math.floor(a_Player:GetPosX());
|
||||
local PlayerZ = math.floor(a_Player:GetPosZ());
|
||||
local WorldName = a_Player:GetWorld():GetName();
|
||||
g_PlayerAreas[PlayerID] = g_Storage:LoadPlayerAreas(a_Player:GetName(), PlayerX, PlayerZ, WorldName);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function ReloadAllPlayersInWorld(a_WorldName)
|
||||
local World = cRoot:Get():GetWorld(a_WorldName);
|
||||
World:ForEachPlayer(LoadPlayerAreas);
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -47,20 +47,6 @@ end
|
|||
|
||||
|
||||
|
||||
--- Loads cPlayerAreas for the specified player from the DB. Returns a cPlayerAreas object
|
||||
function cStorage:LoadPlayerAreas(PlayerName)
|
||||
local res = cPlayerAreas:new();
|
||||
-- TODO: Load the areas from the DB, based on the player's location
|
||||
|
||||
-- DEBUG: Insert a dummy area for testing purposes:
|
||||
res:AddArea(cCuboid(10, 0, 10, 20, 255, 20), false);
|
||||
return res;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Opens the DB and makes sure it has all the columns needed
|
||||
-- Returns true if successful, false otherwise
|
||||
function cStorage:OpenDB()
|
||||
|
@ -72,7 +58,7 @@ function cStorage:OpenDB()
|
|||
end
|
||||
|
||||
if (
|
||||
not(self:CreateTable("Areas", {"ID INTEGER PRIMARY KEY AUTOINCREMENT", "MinX", "MaxX", "MinZ", "MaxZ", "CreatorUserName"})) or
|
||||
not(self:CreateTable("Areas", {"ID INTEGER PRIMARY KEY AUTOINCREMENT", "MinX", "MaxX", "MinZ", "MaxZ", "WorldName", "CreatorUserName"})) or
|
||||
not(self:CreateTable("AllowedUsers", {"AreaID", "UserName"}))
|
||||
) then
|
||||
LOGWARNING(PluginPrefix .. "Cannot create DB tables!");
|
||||
|
@ -86,6 +72,24 @@ end
|
|||
|
||||
|
||||
|
||||
--- Executes the SQL command given, calling the a_Callback for each result
|
||||
-- If the SQL command fails, prints it out on the server console and returns false
|
||||
-- Returns true on success
|
||||
function cStorage:DBExec(a_SQL, a_Callback, a_CallbackParam)
|
||||
local ErrCode = self.DB:exec(a_SQL, a_Callback, a_CallbackParam);
|
||||
if (ErrCode ~= sqlite3.OK) then
|
||||
LOGWARNING(PluginPrefix .. "Error " .. ErrCode .. " (" .. self.DB:errmsg() ..
|
||||
") while processing SQL command >>" .. a_SQL .. "<<"
|
||||
);
|
||||
return false;
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Creates the table of the specified name and columns[]
|
||||
-- If the table exists, any columns missing are added; existing data is kept
|
||||
function cStorage:CreateTable(a_TableName, a_Columns)
|
||||
|
@ -93,9 +97,8 @@ function cStorage:CreateTable(a_TableName, a_Columns)
|
|||
local sql = "CREATE TABLE IF NOT EXISTS '" .. a_TableName .. "' (";
|
||||
sql = sql .. table.concat(a_Columns, ", ");
|
||||
sql = sql .. ")";
|
||||
local ErrCode = self.DB:exec(sql);
|
||||
if (ErrCode ~= sqlite3.OK) then
|
||||
LOGWARNING(PluginPrefix .. "Cannot create DB Table, error " .. ErrCode .. " (" .. self.DB:errmsg() .. ")");
|
||||
if (not(self:DBExec(sql))) then
|
||||
LOGWARNING(PluginPrefix .. "Cannot create DB Table " .. a_TableName);
|
||||
return false;
|
||||
end
|
||||
|
||||
|
@ -124,9 +127,8 @@ function cStorage:CreateTable(a_TableName, a_Columns)
|
|||
end -- for i - Names[] / Values[]
|
||||
return 0;
|
||||
end
|
||||
local ErrCode = self.DB:exec("PRAGMA table_info(" .. a_TableName .. ")", RemoveExistingColumn);
|
||||
if (ErrCode ~= sqlite3.OK) then
|
||||
LOGWARNING(PluginPrefix .. "Cannot query DB table structure, error " .. ErrCode .. " (" .. self.DB:errmsg() ..")");
|
||||
if (not(self:DBExec("PRAGMA table_info(" .. a_TableName .. ")", RemoveExistingColumn))) then
|
||||
LOGWARNING(PluginPrefix .. "Cannot query DB table structure");
|
||||
return false;
|
||||
end
|
||||
|
||||
|
@ -135,9 +137,8 @@ function cStorage:CreateTable(a_TableName, a_Columns)
|
|||
if (#a_Columns > 0) then
|
||||
LOGINFO(PluginPrefix .. "Database table \"" .. a_TableName .. "\" is missing " .. #a_Columns .. " columns, fixing now.");
|
||||
for idx, ColumnName in ipairs(a_Columns) do
|
||||
local ErrCode = self.DB:exec("ALTER TABLE '" .. a_TableName .. "' ADD COLUMN " .. ColumnName);
|
||||
if (ErrCode ~= sqlite3.OK) then
|
||||
LOGWARNING(PluginPrefix .. "Cannot add DB table \"" .. a_TableName .. "\" column \"" .. ColumnName .. "\", error " .. ErrCode .. " (" .. self.DB:errmsg() ..")");
|
||||
if (not(self:DBExec("ALTER TABLE '" .. a_TableName .. "' ADD COLUMN " .. ColumnName))) then
|
||||
LOGWARNING(PluginPrefix .. "Cannot add DB table \"" .. a_TableName .. "\" column \"" .. ColumnName .. "\"");
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
@ -151,8 +152,26 @@ end
|
|||
|
||||
|
||||
|
||||
--- Loads cPlayerAreas for the specified player from the DB. Returns a cPlayerAreas object
|
||||
function cStorage:LoadPlayerAreas(a_PlayerName, a_PlayerX, a_PlayerZ, a_WorldName)
|
||||
local res = cPlayerAreas:new();
|
||||
|
||||
-- TODO: Load the areas from the DB, based on the player's location
|
||||
-- local sql = "SELECT MinX, MaxX, MinZ, MaxZ FROM Areas WHERE";
|
||||
|
||||
LOGWARNING("cStorage:LoadPlayerAreas(): Not implemented yet!");
|
||||
|
||||
-- DEBUG: Insert a dummy area for testing purposes:
|
||||
res:AddArea(cCuboid(10, 0, 10, 20, 255, 20), false);
|
||||
return res;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Adds a new area into the DB. a_AllowedNames is a table listing all the players that are allowed in the area
|
||||
function cStorage:AddArea(a_Cuboid, a_CreatorName, a_AllowedNames)
|
||||
function cStorage:AddArea(a_Cuboid, a_WorldName, a_CreatorName, a_AllowedNames)
|
||||
-- Store the area in the DB
|
||||
local ID = -1;
|
||||
local function RememberID(UserData, NumCols, Values, Names)
|
||||
|
@ -164,8 +183,9 @@ function cStorage:AddArea(a_Cuboid, a_CreatorName, a_AllowedNames)
|
|||
return 0;
|
||||
end
|
||||
local sql =
|
||||
"INSERT INTO Areas (ID, MinX, MaxX, MinZ, MaxZ, CreatorUserName) VALUES (NULL, " ..
|
||||
a_Cuboid.p1.x .. ", " .. a_Cuboid.p2.x .. ", " .. a_Cuboid.p1.z .. ", " .. a_Cuboid.p2.z .. ", '" .. a_CreatorName ..
|
||||
"INSERT INTO Areas (ID, MinX, MaxX, MinZ, MaxZ, WorldName, CreatorUserName) VALUES (NULL, " ..
|
||||
a_Cuboid.p1.x .. ", " .. a_Cuboid.p2.x .. ", " .. a_Cuboid.p1.z .. ", " .. a_Cuboid.p2.z ..
|
||||
", '" .. a_WorldName .. "', '" .. a_CreatorName ..
|
||||
"'); SELECT last_insert_rowid() as ID";
|
||||
if (not(self:DBExec(sql, RememberID))) then
|
||||
LOGWARNING(PluginPrefix .. "SQL Error while inserting new area");
|
||||
|
@ -181,24 +201,7 @@ function cStorage:AddArea(a_Cuboid, a_CreatorName, a_AllowedNames)
|
|||
local sql = "INSERT INTO AllowedUsers (AreaID, UserName) VALUES (" .. ID .. ", '" .. Name .. "')";
|
||||
if (not(self:DBExec(sql))) then
|
||||
LOGWARNING(PluginPrefix .. "SQL Error while inserting new area's allowed player " .. Name);
|
||||
end;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Executes the SQL command given, calling the a_Callback for each result
|
||||
-- If the SQL command fails, prints it out on the server console and returns false
|
||||
-- Returns true on success
|
||||
function cStorage:DBExec(a_SQL, a_Callback, a_CallbackParam)
|
||||
local ErrCode = self.DB:exec(a_SQL, a_Callback, a_CallbackParam);
|
||||
if (ErrCode ~= sqlite3.OK) then
|
||||
LOGWARNING(PluginPrefix .. "Error " .. ErrCode .. " (" .. self.DB:errmsg() ..
|
||||
") while processing SQL command >>" .. a_SQL .. "<<"
|
||||
);
|
||||
return false;
|
||||
end
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
@ -207,3 +210,42 @@ end
|
|||
|
||||
|
||||
|
||||
function cStorage:DelArea(a_WorldName, a_AreaID)
|
||||
-- Since all areas are stored in a single DB (for now), the worldname parameter isn't used at all
|
||||
-- Later if we change to a per-world DB, we'll need the world name
|
||||
|
||||
-- Delete from both tables simultaneously
|
||||
local sql =
|
||||
"DELETE FROM Areas WHERE ID=" .. a_AreaID .. ";" ..
|
||||
"DELETE FROM AllowedPlayers WHERE AreaID=" .. a_AreaID;
|
||||
if (not(self:DBExec(sql))) then
|
||||
LOGWARNING(PluginPrefix .. "SQL error while deleting area " .. a_AreaID .. " from world \"" .. a_WorldName .. "\"");
|
||||
return false;
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Removes the user from the specified area
|
||||
function cStorage:RemoveUser(a_AreaID, a_UserName, a_WorldName)
|
||||
-- TODO
|
||||
LOGWARNING("cStorage:RemoveUser(): Not implemented yet!");
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Removes the user from all areas in the specified world
|
||||
function cStorage:RemoveUserAll(a_UserName, a_WorldName)
|
||||
-- TODO
|
||||
LOGWARNING("cStorage:RemoveUserAll(): Not implemented yet!");
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue