Cuberite Forum
Logger - Printable Version

+- Cuberite Forum (https://forum.cuberite.org)
+-- Forum: Plugins (https://forum.cuberite.org/forum-1.html)
+--- Forum: Plugin Releases (https://forum.cuberite.org/forum-2.html)
+--- Thread: Logger (/thread-2085.html)

Pages: 1 2 3


Logger - DrMasik - 08-18-2015

I'm sorry for bad English.

It's my first plugin for MCServer and Lua language and first soure on github.com Smile

Task:
Record all commands on the server console and user's game console.

About plugin.
Plugin save data into sqlite3 file "logger.sqlite3" into root directory of server.

Supported commands from server console.
logger clean - delete data from database
logger count - records count
logger show [<count>] - Display database records

Future:
- Your suggestions

Last update: 2015.08.19
Current version: 2

GitHub
Download


RE: Logger - NiLSPACE - 08-18-2015

Welcome to the forum and congratulations on your first plugin Smile

This is a nice idea, but I think it's vulnerable to SQL injections. This can be easy to fix by changing "Message" to "EscapeString(Message)" in this line


RE: Logger - DrMasik - 08-18-2015

(08-18-2015, 06:15 AM)NiLSPACE Wrote: Welcome to the forum and congratulations on your first plugin Smile

This is a nice idea, but I think it's vulnerable to SQL injections. This can be easy to fix by changing "Message" to "EscapeString(Message)" in this line

Thank you. I'll correct it.


RE: Logger - xoft - 08-18-2015

Nice first plugin.

As NiLSPACE already noted, it is somewhat vulnerable to SQL injection, but I don't agree with his solution. You should instead use prepared statements to insert values into the DB:
local stmt = LOG_DB:prepare("INSERT INTO data (login, message, date) VALUES (?, ?, ?)")
stmt:bind_values(Player:GetName(), Message, os.time())
stmt:execute()
This way the code is clean from any SQL injections and the actual statement is even a bit easier to read.

I'd suggest you don't use the ON_EXECUTE_COMMAND hook, but rather register your command in the regular way, using cPluginManager:BindCommand(), or even better, using the Info.lua file. See here for details: http://luaapi.cuberite.org/InfoFile.html
That way your command gets shown in the help and the server checks that only one plugin registers your command - the admins get a warning message if two plugins try to register the "logger" command.


RE: Logger - DrMasik - 08-19-2015

Update to version 2015081801.
- Add more security. SQL injection. (Thanks NiLSPACE and Xoft)

Future:
- Register commands intu MCServer
- Show records in database


RE: Logger - DrMasik - 08-19-2015

Update to version 2015081802.
- Register commands into MCServer

Future:
- Show records in database


RE: Logger - xoft - 08-19-2015

Looks good.
Now change your command handlers so that they return the text to log, rather than logging it directly. This will allow you to use the commands through RCON as well.
function CmdHandler()
  -- Process command
  return true, "Message to log"
end



RE: Logger - DrMasik - 08-19-2015

Update to version 2015081902.
- Show records in database
- Add index login and login_date

Future:
- Your suggestions


RE: Logger - xoft - 08-20-2015

The HandleConsoleDBShow could use some refactoring:
- Lines 178 - 181 can be replaced with a simple "split_count = #Split"
- There's no need to check array boundaries in Lua - all elements outside the boundaries are implicitly "nil". It's much better to check "if (Split[3])" than "if (#Split > 2)", because the first condition does one table lookup, while the latter does an element count (which is an O(N) operation where N is the total number of elements in the array).
- I think the limit should default to a reasonable number, rather than "unlimited" when no param is given. You don't want the entire history of a year-old server spewed out when the admin forgets the limit parameter Smile

Therefore it should be possible to replace lines 178 - 188 with a single line:
ret_rows_count = " LIMIT " .. math.floor(tonumber(Split[3]) or 30)
(tonumber works on everything you throw at it, returning nil when it's not a recognizable number, the "or" operator then makes sure that if no number is returned, 30 (the default limit) is used. Also note that the semicolon is not needed for SQL commands, unless you're executing multiple commands with a single execute() call)


RE: Logger - xoft - 08-20-2015

As for the display part of that function, it's okay for now, but not good for larger projects, you should get into the habit of using table.concat to concatenate multiple strings (100+ strings) together. Best code:
local out = {}
local n = 1
for row in LOG_DB:nrows(...) do
  out[n] = row.date .. " | " .. row.login .. " | " .. row.message
  n = n + 1
end
return true, table.concat(out, "\n")