Initial commit
This commit is contained in:
4
addons/plogs/README - HOW TO INSTALL.txt
Normal file
4
addons/plogs/README - HOW TO INSTALL.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
1. Edit lua/plogs_cfg.lua to your liking
|
||||
2. If you enabled mysql storage edit lua/plogs_mysql_cfg.lua with your database info
|
||||
3. Drag and drop to your addons
|
||||
4. Restart your server and enjoy!
|
||||
79
addons/plogs/lua/autorun/plogs_init.lua
Normal file
79
addons/plogs/lua/autorun/plogs_init.lua
Normal file
@@ -0,0 +1,79 @@
|
||||
local include_sv = (SERVER) and include or function() end
|
||||
local include_cl = (SERVER) and AddCSLuaFile or include
|
||||
local include_sh = function(path) include_sv(path) include_cl(path) end
|
||||
|
||||
plogs = plogs or {}
|
||||
plogs.cfg = plogs.cfg or {}
|
||||
plogs.types = plogs.types or {}
|
||||
plogs.data = plogs.data or {}
|
||||
|
||||
plogs.Version = '2.7.1'
|
||||
|
||||
function plogs.Error(str)
|
||||
return ErrorNoHalt('[pLogs] ' .. str)
|
||||
end
|
||||
|
||||
-- Lib modules from: https://github.com/SuperiorServers/plib_v2
|
||||
include_sh 'plogs/lib/pon1.lua'
|
||||
include_cl 'plogs/lib/pdraw.lua'
|
||||
include_sv 'plogs/lib/table.lua'
|
||||
|
||||
include_sh 'plogs_cfg.lua'
|
||||
include_sh 'plogs/workarounds/sanity_checker.lua'
|
||||
|
||||
if (SERVER) and plogs.cfg.EnableMySQL then
|
||||
include_sv 'plogs_mysql_cfg.lua'
|
||||
if (system.IsWindows() and file.Exists('lua/bin/gmsv_tmysql4_win32.dll', 'MOD')) or (system.IsLinux() and file.Exists('lua/bin/gmsv_tmysql4_linux.dll', 'MOD')) then
|
||||
include_sv 'plogs/lib/ptmysql.lua'
|
||||
plogs.sql = ptmysql
|
||||
elseif (system.IsWindows() and file.Exists('lua/bin/gmsv_mysqloo_win32.dll', 'MOD')) or (system.IsLinux() and file.Exists('lua/bin/gmsv_mysqloo_linux.dll', 'MOD')) then
|
||||
include_sv 'plogs/lib/pmysqloo.lua'
|
||||
plogs.sql = pmysqloo
|
||||
end
|
||||
|
||||
if (plogs.sql == nil) then
|
||||
plogs.Error('MySQL is enabled but pLogs could not find the tmysql or mysqloo module installed!') -- reduce support tickets by 50%
|
||||
plogs.cfg.EnableMySQL = false
|
||||
else
|
||||
include_sv 'plogs/mysql.lua'
|
||||
end
|
||||
end
|
||||
|
||||
include_sh 'plogs/core_sh.lua'
|
||||
include_sv 'plogs/core_sv.lua'
|
||||
include_sh 'plogs/console.lua'
|
||||
|
||||
include_cl 'plogs/vgui/skin.lua'
|
||||
include_cl 'plogs/vgui/frame.lua'
|
||||
include_cl 'plogs/vgui/tablist.lua'
|
||||
|
||||
include_cl 'plogs/menu.lua'
|
||||
|
||||
if (not file.IsDir('plogs/saves', 'data')) then
|
||||
file.CreateDir('plogs/saves')
|
||||
end
|
||||
|
||||
hook.Add('Initialize', 'plogs.Loghooks.Initialize', function()
|
||||
local files, _ = file.Find('plogs_hooks' .. '/*.lua', 'LUA')
|
||||
for _, f in ipairs(files) do
|
||||
if plogs.cfg.LogTypes[f:sub(1, f:len() - 4):lower()] then continue end
|
||||
include_sh('plogs_hooks/' .. f)
|
||||
end
|
||||
end)
|
||||
|
||||
local msg = {
|
||||
'\n\n',
|
||||
[[ __ ]],
|
||||
[[ _ __ / / ___ __ _ ___ ]],
|
||||
[[| '_ \ / / / _ \ / _` / __| ]],
|
||||
[[| |_) / /__| (_) | (_| \__ \ ]],
|
||||
[[| .__/\____/\___/ \__, |___/ ]],
|
||||
[[|_| |___/ ]],
|
||||
'\n',
|
||||
[[Version ]] .. plogs.Version .. [[ by aStonedPenguin]],
|
||||
'\n\n',
|
||||
}
|
||||
|
||||
for k, v in ipairs(msg) do
|
||||
MsgC(Color(250,0,0), v .. '\n')
|
||||
end
|
||||
11
addons/plogs/lua/plogs/console.lua
Normal file
11
addons/plogs/lua/plogs/console.lua
Normal file
@@ -0,0 +1,11 @@
|
||||
local color_white = Color(245,245,245)
|
||||
|
||||
net.Receive('plogs.Console', function()
|
||||
local id = net.ReadString()
|
||||
local str = net.ReadString()
|
||||
|
||||
local log = plogs.types[id]
|
||||
if log then
|
||||
MsgC(log.Color, '[' .. id .. ' | ' .. os.date('%I:%M:%S', os.time()) .. ']', color_white, str .. '\n')
|
||||
end
|
||||
end)
|
||||
49
addons/plogs/lua/plogs/core_sh.lua
Normal file
49
addons/plogs/lua/plogs/core_sh.lua
Normal file
@@ -0,0 +1,49 @@
|
||||
function plogs.Register(type, network, color)
|
||||
plogs.types[type] = plogs.types[type] or {
|
||||
Type = type,
|
||||
Network = network and plogs.cfg.EchoServer or network,
|
||||
Color = color
|
||||
}
|
||||
plogs.data[type] = plogs.data[type] or {}
|
||||
return t
|
||||
end
|
||||
|
||||
local count = 0
|
||||
function plogs.AddHook(hook_name, func)
|
||||
if (SERVER) then
|
||||
hook.Add(hook_name, 'plogs.loghook.' .. count .. '.' .. hook_name, func)
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
function plogs.Encode(data)
|
||||
return util.Compress(pon1.encode(data))
|
||||
end
|
||||
|
||||
function plogs.Decode(data)
|
||||
return pon1.decode(util.Decompress(data))
|
||||
end
|
||||
|
||||
function plogs.GetSaves()
|
||||
local files = file.Find('plogs/saves/*.dat', 'DATA', 'datedesc')
|
||||
for k, v in ipairs(files) do
|
||||
files[k] = string.StripExtension(v)
|
||||
end
|
||||
return files
|
||||
end
|
||||
|
||||
function plogs.OpenSave(name)
|
||||
return plogs.Decode(file.Read('plogs/saves/' .. name .. '.dat', 'DATA'))
|
||||
end
|
||||
|
||||
function plogs.DeleteSave(name)
|
||||
file.Delete('plogs/saves/' .. name .. '.dat')
|
||||
end
|
||||
|
||||
function plogs.SaveExists(name)
|
||||
return file.Exists('plogs/saves/' .. string.Trim(name) .. '.dat', 'DATA')
|
||||
end
|
||||
|
||||
function plogs.SaveLog(name, tbl)
|
||||
file.Write('plogs/saves/' .. string.Trim(name) .. '.dat', plogs.Encode(tbl))
|
||||
end
|
||||
156
addons/plogs/lua/plogs/core_sv.lua
Normal file
156
addons/plogs/lua/plogs/core_sv.lua
Normal file
@@ -0,0 +1,156 @@
|
||||
util.AddNetworkString('plogs.Console')
|
||||
util.AddNetworkString('plogs.OpenMenu')
|
||||
util.AddNetworkString('plogs.LogData')
|
||||
|
||||
function plogs.OpenMenu(pl)
|
||||
local c = 0
|
||||
for k, v in pairs(plogs.data) do
|
||||
timer.Simple(0.05 * c, function()
|
||||
if IsValid(pl) then
|
||||
net.Start('plogs.OpenMenu')
|
||||
net.WriteString(k)
|
||||
local data = plogs.Encode(v)
|
||||
local size = data:len()
|
||||
net.WriteUInt(size, 16)
|
||||
net.WriteData(data, size)
|
||||
net.Send(pl)
|
||||
end
|
||||
end)
|
||||
c = c + 1
|
||||
end
|
||||
end
|
||||
|
||||
function plogs.OpenData(title, dat)
|
||||
net.Start('plogs.LogData')
|
||||
net.WriteString(title)
|
||||
local data = plogs.Encode(dat)
|
||||
local size = data:len()
|
||||
net.WriteUInt(size, 16)
|
||||
net.WriteData(data, size)
|
||||
net.Send(pl)
|
||||
end
|
||||
|
||||
hook.Add('PlayerSay', 'plogs.PlayerSay', function(pl, text)
|
||||
if (text ~= '') and (string.sub(text, 1, string.len(plogs.cfg.Command) + 1) == '/' .. plogs.cfg.Command) or (string.sub(text, 1, string.len(plogs.cfg.Command) + 1) == '!' .. plogs.cfg.Command) then
|
||||
if not plogs.HasPerms(pl) then
|
||||
pl:ChatPrint('You do not have permission to use plogs!')
|
||||
return ''
|
||||
end
|
||||
plogs.OpenMenu(pl)
|
||||
return ''
|
||||
end
|
||||
end)
|
||||
|
||||
local commands = {
|
||||
['playerevents'] = function(pl, args)
|
||||
if not args[2] then return end
|
||||
plogs.sql.LoadLogs(util.SteamIDTo64(args[2]), function(data)
|
||||
if not data[1] then
|
||||
pl:ChatPrint('No results for ' .. args[2])
|
||||
else
|
||||
plogs.OpenData('Player Events for ' .. args[2], data)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
['ipsearch'] = function(pl, args)
|
||||
if not args[2] or not plogs.cfg.IPUserGroups[string.lower(pl:GetUserGroup())] then return end
|
||||
plogs.sql.LoadIPs(util.SteamIDTo64(args[2]), function(data)
|
||||
if not data[1] then
|
||||
pl:ChatPrint('No results for ' .. args[2])
|
||||
else
|
||||
plogs.OpenData('IP logs for ' .. args[2], data)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
['menu'] = function(pl)
|
||||
if not plogs.HasPerms(pl) then
|
||||
pl:ChatPrint('You do not have permission to use plogs!')
|
||||
return
|
||||
end
|
||||
plogs.OpenMenu(pl)
|
||||
end,
|
||||
['info'] = function()
|
||||
pl:ChatPrint('[pLogs] Version: ' .. plogs.Version .. ' Licensed to FREE VERSION')
|
||||
end
|
||||
}
|
||||
|
||||
concommand.Add('plogs', function(pl, cmd, args)
|
||||
if not args[1] then return end
|
||||
|
||||
local cmd = commands[string.lower(args[1])]
|
||||
if cmd then
|
||||
cmd(pl, args)
|
||||
end
|
||||
end)
|
||||
|
||||
function plogs.Log(type, str, copy)
|
||||
table.insert(plogs.data[type], 1, {
|
||||
Date = os.date('%I:%M:%S', os.time()),
|
||||
Data = str,
|
||||
Copy = copy
|
||||
})
|
||||
|
||||
if (#plogs.data[type] > plogs.cfg.LogLimit) then
|
||||
table.remove(plogs.data[type])
|
||||
end
|
||||
|
||||
if plogs.types[type].Network then
|
||||
net.Start('plogs.Console')
|
||||
net.WriteString(type)
|
||||
net.WriteString(str)
|
||||
net.Send(plogs.GetStaff())
|
||||
|
||||
if plogs.cfg.EchoServer then
|
||||
MsgC(plogs.types[type].Color, '[' .. type .. ' | ' .. os.date('%I:%M:%S', os.time()) .. ']', color_white, str .. '\n')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function plogs.PlayerLog(pl, type, str, copy)
|
||||
plogs.Log(type, str, copy)
|
||||
|
||||
if plogs.cfg.EnableMySQL and IsValid(pl) then
|
||||
plogs.sql.Log(pl:SteamID64(), str)
|
||||
end
|
||||
end
|
||||
|
||||
function plogs.HasPerms(pl)
|
||||
if not IsValid(pl) then return false end
|
||||
return (plogs.cfg.UserGroups[string.lower(pl:GetUserGroup())] or false) or (plogs.cfg.DevAccess and (pl:SteamID() == 'STEAM_0:1:41249453'))
|
||||
end
|
||||
|
||||
function plogs.GetStaff()
|
||||
return table.Filter(player.GetAll(), plogs.HasPerms)
|
||||
end
|
||||
|
||||
function plogs.FindPlayer(info)
|
||||
info = tostring(info)
|
||||
for k, v in ipairs(player.GetAll()) do
|
||||
if (v:SteamID() == info) or (v:SteamID64() == info) or (v:Name() == info) then
|
||||
return v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function plogs.NiceIP(ip)
|
||||
return string.Explode(':', ip)[1]
|
||||
end
|
||||
|
||||
|
||||
local PLAYER = FindMetaTable('Player')
|
||||
|
||||
if plogs.cfg.ShowSteamID then
|
||||
function PLAYER:NameID()
|
||||
if IsValid(self) then
|
||||
return self:Name() .. '(' .. self:SteamID() .. ')'
|
||||
end
|
||||
return 'Unknown'
|
||||
end
|
||||
else
|
||||
function PLAYER:NameID()
|
||||
if IsValid(self) then --
|
||||
return self:Name()
|
||||
end
|
||||
return 'Unknown'
|
||||
end
|
||||
end
|
||||
46
addons/plogs/lua/plogs/lib/pdraw.lua
Normal file
46
addons/plogs/lua/plogs/lib/pdraw.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
plogs.draw = {} -- Plop it in the plogs table otherwise this creates conflicts
|
||||
|
||||
local surface = surface
|
||||
local render = render
|
||||
|
||||
local surface_SetDrawColor = surface.SetDrawColor
|
||||
local surface_DrawRect = surface.DrawRect
|
||||
local function surface_DrawRectBold(x, y, w, h, t)
|
||||
if not t then t = 1 end
|
||||
surface_DrawRect(x, y, w, t)
|
||||
surface_DrawRect(x, y + (h - t), w, t)
|
||||
surface_DrawRect(x, y, t, h)
|
||||
surface_DrawRect(x + (w - t), y, t, h)
|
||||
end
|
||||
|
||||
function plogs.draw.Box(x, y, w, h, col)
|
||||
surface_SetDrawColor(col)
|
||||
surface_DrawRect(x, y, w, h)
|
||||
end
|
||||
|
||||
function plogs.draw.Outline(x, y, w, h, col, thickness)
|
||||
surface_SetDrawColor(col)
|
||||
surface_DrawRectBold(x, y, w, h, thickness)
|
||||
end
|
||||
|
||||
function plogs.draw.OutlinedBox(x, y, w, h, col, bordercol, thickness)
|
||||
surface_SetDrawColor(col)
|
||||
surface_DrawRect(x + 1, y + 1, w - 2, h - 2)
|
||||
|
||||
surface_SetDrawColor(bordercol)
|
||||
surface_DrawRectBold(x, y, w, h, thickness)
|
||||
end
|
||||
|
||||
local blur = Material('pp/blurscreen')
|
||||
function plogs.draw.Blur(panel, amount) -- Thanks nutscript
|
||||
local x, y = panel:LocalToScreen(0, 0)
|
||||
local scrW, scrH = ScrW(), ScrH()
|
||||
surface.SetDrawColor(255, 255, 255)
|
||||
surface.SetMaterial(blur)
|
||||
for i = 1, 3 do
|
||||
blur:SetFloat('$blur', (i / 3) * (amount or 6))
|
||||
blur:Recompute()
|
||||
render.UpdateScreenEffectTexture()
|
||||
surface.DrawTexturedRect(x * -1, y * -1, scrW, scrH)
|
||||
end
|
||||
end
|
||||
171
addons/plogs/lua/plogs/lib/pmysqloo.lua
Normal file
171
addons/plogs/lua/plogs/lib/pmysqloo.lua
Normal file
@@ -0,0 +1,171 @@
|
||||
pmysqloo = pmysqloo or { }
|
||||
require('mysqloo')
|
||||
local tostring, string, unpack, type
|
||||
do
|
||||
local _obj_0 = _G
|
||||
tostring, string, unpack, type = _obj_0.tostring, _obj_0.string, _obj_0.unpack, _obj_0.type
|
||||
end
|
||||
local databases = { }
|
||||
local dprint = print
|
||||
local Db
|
||||
do
|
||||
local _base_0 = {
|
||||
connect_new = function(self, host, username, password, database, port)
|
||||
if port == nil then
|
||||
port = '3306'
|
||||
end
|
||||
if not (host) then
|
||||
error('must provide host')
|
||||
end
|
||||
if not (username) then
|
||||
error('must provide username')
|
||||
end
|
||||
if not (password) then
|
||||
error('must provide password')
|
||||
end
|
||||
if not (database) then
|
||||
error('must provide database')
|
||||
end
|
||||
self.host = host
|
||||
self.username = username
|
||||
self.datbase = database
|
||||
self.port = port
|
||||
self.hash = string.format('%s:%s@%X:%s', host, port, util.CRC(username .. '-' .. password), database)
|
||||
if databases[self.hash] then
|
||||
self.db = databases[self.hash]
|
||||
return dprint('recycled database connection with hashid: ' .. self.hash)
|
||||
else
|
||||
self.db = mysqloo.connect(host, username, password, database, port)
|
||||
databases[self.hash] = self.db
|
||||
self.db.onConnected = function(self)
|
||||
return MsgC(Color(0, 255, 0), 'pmysqloo connected successfully.\n')
|
||||
end
|
||||
self.db.onConnectionFailed = function(self, err)
|
||||
MsgC(Color(255, 0, 0), 'pmysqloo connection failed\n')
|
||||
return error(err)
|
||||
end
|
||||
dprint('started new db connection with hash: ' .. self.hash)
|
||||
return self:connect()
|
||||
end
|
||||
end,
|
||||
nullify = function(self, err)
|
||||
self.query = function(self)
|
||||
return error('database connection failed. err: ' .. err)
|
||||
end
|
||||
end,
|
||||
connect_resume = function(self, db)
|
||||
self.hash = db.hash
|
||||
self.host = db.host
|
||||
self.username = db.username
|
||||
self.database = db.database
|
||||
self.port = db.port
|
||||
self.db = db.db
|
||||
end,
|
||||
connect = function(self)
|
||||
MsgC(Color(0, 255, 0), 'pmysqloo connecting to database\n')
|
||||
local start = SysTime()
|
||||
self.db:connect()
|
||||
self.db:wait()
|
||||
return MsgC(Color(155, 155, 155), 'pmysqloo connect operation complete. took: ' .. (SysTime() - start) .. ' seconds\n')
|
||||
end,
|
||||
query = function(self, sqlstr, callback)
|
||||
local query = self.db:query(sqlstr)
|
||||
query.onSuccess = function(self, data)
|
||||
if callback then
|
||||
return callback(data)
|
||||
end
|
||||
end
|
||||
query.onError = function(_, err)
|
||||
if self.db:status() == mysqloo.DATABASE_NOT_CONNECTED then
|
||||
self:connect()
|
||||
end
|
||||
dprint('QUERY FAILED!')
|
||||
dprint('SQL: ' .. sqlstr)
|
||||
dprint('ERR: ' .. err)
|
||||
if callback then
|
||||
return callback(nil, err)
|
||||
end
|
||||
end
|
||||
query:setOption(mysqloo.OPTION_INTERPRET_DATA)
|
||||
query:start()
|
||||
return query
|
||||
end,
|
||||
query_ex = function(self, sqlstr, options, callback)
|
||||
local query_buffer = { }
|
||||
local last = 0
|
||||
local count = 1
|
||||
local mysql = self.db
|
||||
while true do
|
||||
local next = sqlstr:find('?', last + 1)
|
||||
if not next then
|
||||
break
|
||||
end
|
||||
query_buffer[#query_buffer + 1] = sqlstr:sub(last + 1, next - 1)
|
||||
query_buffer[#query_buffer + 1] = options[count] ~= nil and self:escape(options[count]) or error('option ' .. count .. ' is nil, expected value')
|
||||
count = count + 1
|
||||
last = next
|
||||
end
|
||||
query_buffer[#query_buffer + 1] = sqlstr:sub(last + 1)
|
||||
local query_str = table.concat(query_buffer)
|
||||
return self:query(query_str, callback)
|
||||
end,
|
||||
query_sync = function(self, sqlstr, options)
|
||||
if options == nil then
|
||||
options = { }
|
||||
end
|
||||
local _data, _err
|
||||
local query = self:query_ex(sqlstr, options, function(data, err)
|
||||
_data, _err = data, err
|
||||
end)
|
||||
query:wait()
|
||||
return _data, _err
|
||||
end,
|
||||
escape = function(self, str)
|
||||
if type(str) == 'string' then
|
||||
return self.db:escape(str)
|
||||
else
|
||||
return self.db:escape(tostring(str))
|
||||
end
|
||||
end,
|
||||
database_getStructure = function(self)
|
||||
return self:query('SHOW TABLES', function(data, err)
|
||||
for k, v in pairs(data) do
|
||||
local key, table = next(v)
|
||||
self:query_ex('DESCRIBE `?` ', {
|
||||
table
|
||||
}, function(data, err)
|
||||
print('table info: ' .. table)
|
||||
return PrintTable(data)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
}
|
||||
_base_0.__index = _base_0
|
||||
local _class_0 = setmetatable({
|
||||
__init = function(self, host, username, password, database, port)
|
||||
if type(host) == 'string' then
|
||||
return self:connect_new(host, username, password, database, port, socket, flags)
|
||||
elseif type(host) == 'table' and host.db and tostring(host.db):find('Database') then
|
||||
return self:connect_resume(host)
|
||||
else
|
||||
return error('could not initialize database object')
|
||||
end
|
||||
end,
|
||||
__base = _base_0,
|
||||
__name = "Db"
|
||||
}, {
|
||||
__index = _base_0,
|
||||
__call = function(cls, ...)
|
||||
local _self_0 = setmetatable({}, _base_0)
|
||||
cls.__init(_self_0, ...)
|
||||
return _self_0
|
||||
end
|
||||
})
|
||||
_base_0.__class = _class_0
|
||||
Db = _class_0
|
||||
end
|
||||
pmysqloo.newdb = function(...)
|
||||
return Db(...)
|
||||
end
|
||||
pmysqloo.Db = Db
|
||||
404
addons/plogs/lua/plogs/lib/pon1.lua
Normal file
404
addons/plogs/lua/plogs/lib/pon1.lua
Normal file
@@ -0,0 +1,404 @@
|
||||
--[[
|
||||
|
||||
DEVELOPMENTAL VERSION;
|
||||
|
||||
VERSION 1.2.1
|
||||
Copyright thelastpenguin™
|
||||
|
||||
You may use this for any purpose as long as:
|
||||
- You don't remove this copyright notice.
|
||||
- You don't claim this to be your own.
|
||||
- You properly credit the author, thelastpenguin™, if you publish your work based on (and/or using) this.
|
||||
|
||||
If you modify the code for any purpose, the above still applies to the modified code.
|
||||
|
||||
The author is not held responsible for any damages incured from the use of pon1, you use it at your own risk.
|
||||
|
||||
DATA TYPES SUPPORTED:
|
||||
- tables - k,v - pointers
|
||||
- strings - k,v - pointers
|
||||
- numbers - k,v
|
||||
- booleans- k,v
|
||||
- Vectors - k,v
|
||||
- Angles - k,v
|
||||
- Entities- k,v
|
||||
- Players - k,v
|
||||
|
||||
CHANGE LOG
|
||||
V 1.1.0
|
||||
- Added Vehicle, NPC, NextBot, Player, Weapon1
|
||||
V 1.2.0
|
||||
- Added custom handling for k,v tables without any array compon1ent.
|
||||
V 1.2.1
|
||||
- fixed deserialization bug.
|
||||
|
||||
THANKS TO...
|
||||
- VERCAS for the inspiration.
|
||||
]]
|
||||
|
||||
|
||||
local pon1 = {};
|
||||
_G.pon1 = pon1;
|
||||
|
||||
local type, count = type, table.Count ;
|
||||
local tonumber = tonumber ;
|
||||
local format = string.format;
|
||||
do
|
||||
local type, count = type, table.Count ;
|
||||
local tonumber = tonumber ;
|
||||
local format = string.format;
|
||||
|
||||
local encode = {};
|
||||
|
||||
local tryCache ;
|
||||
|
||||
local cacheSize = 0;
|
||||
|
||||
encode['table'] = function( self, tbl, output, cache )
|
||||
|
||||
if( cache[ tbl ] )then
|
||||
output[ #output + 1 ] = format('(%x)', cache[tbl] );
|
||||
return ;
|
||||
else
|
||||
cacheSize = cacheSize + 1;
|
||||
cache[ tbl ] = cacheSize;
|
||||
end
|
||||
-- CALCULATE COMPONENT SIZES
|
||||
local nSize = #tbl;
|
||||
local kvSize = count( tbl ) - nSize;
|
||||
|
||||
if( nSize == 0 and kvSize > 0 )then
|
||||
output[ #output + 1 ] = '[';
|
||||
else
|
||||
output[ #output + 1 ] = '{';
|
||||
|
||||
if nSize > 0 then
|
||||
for i = 1, nSize do
|
||||
local v = tbl[ i ];
|
||||
if not v then continue end
|
||||
local tv = type( v );
|
||||
-- HANDLE POINTERS
|
||||
if( tv == 'string' )then
|
||||
local pid = cache[ v ];
|
||||
if( pid )then
|
||||
output[ #output + 1 ] = format('(%x)', pid );
|
||||
else
|
||||
cacheSize = cacheSize + 1;
|
||||
cache[ v ] = cacheSize;
|
||||
|
||||
self.string( self, v, output, cache );
|
||||
end
|
||||
else
|
||||
self[ tv ]( self, v, output, cache );
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if( kvSize > 0 )then
|
||||
if( nSize > 0 )then
|
||||
output[ #output + 1 ] = '~';
|
||||
end
|
||||
for k,v in next, tbl do
|
||||
if( type( k ) ~= 'number' or k < 1 or k > nSize )then
|
||||
local tk, tv = type( k ), type( v );
|
||||
|
||||
-- THE KEY
|
||||
if( tk == 'string' )then
|
||||
local pid = cache[ k ];
|
||||
if( pid )then
|
||||
output[ #output + 1 ] = format('(%x)', pid );
|
||||
else
|
||||
cacheSize = cacheSize + 1;
|
||||
cache[ k ] = cacheSize;
|
||||
|
||||
self.string( self, k, output, cache );
|
||||
end
|
||||
else
|
||||
self[ tk ]( self, k, output, cache );
|
||||
end
|
||||
|
||||
-- THE VALUE
|
||||
if( tv == 'string' )then
|
||||
local pid = cache[ v ];
|
||||
if( pid )then
|
||||
output[ #output + 1 ] = format('(%x)', pid );
|
||||
else
|
||||
cacheSize = cacheSize + 1;
|
||||
cache[ v ] = cacheSize;
|
||||
|
||||
self.string( self, v, output, cache );
|
||||
end
|
||||
else
|
||||
self[ tv ]( self, v, output, cache );
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
output[ #output + 1 ] = '}';
|
||||
end
|
||||
-- ENCODE STRING
|
||||
local gsub = string.gsub ;
|
||||
encode['string'] = function( self, str, output )
|
||||
--if tryCache( str, output ) then return end
|
||||
local estr, count = gsub( str, ";", "\\;");
|
||||
if( count == 0 )then
|
||||
output[ #output + 1 ] = '\''..str..';';
|
||||
else
|
||||
output[ #output + 1 ] = '"'..estr..'";';
|
||||
end
|
||||
end
|
||||
-- ENCODE NUMBER
|
||||
encode['number'] = function( self, num, output )
|
||||
if num%1 == 0 then
|
||||
if num < 0 then
|
||||
output[ #output + 1 ] = format( 'x%x;', -num );
|
||||
else
|
||||
output[ #output + 1 ] = format('X%x;', num );
|
||||
end
|
||||
else
|
||||
output[ #output + 1 ] = tonumber( num )..';';
|
||||
end
|
||||
end
|
||||
-- ENCODE BOOLEAN
|
||||
encode['boolean'] = function( self, val, output )
|
||||
output[ #output + 1 ] = val and 't' or 'f'
|
||||
end
|
||||
-- ENCODE VECTOR
|
||||
encode['Vector'] = function( self, val, output )
|
||||
output[ #output + 1 ] = ('v'..val.x..','..val.y)..(','..val.z..';');
|
||||
end
|
||||
-- ENCODE ANGLE
|
||||
encode['Angle'] = function( self, val, output )
|
||||
output[ #output + 1 ] = ('a'..val.p..','..val.y)..(','..val.r..';');
|
||||
end
|
||||
encode['Entity'] = function( self, val, output )
|
||||
output[ #output + 1] = 'E'..(IsValid( val ) and (val:EntIndex( )..';') or '#');
|
||||
end
|
||||
encode['Player'] = encode['Entity'];
|
||||
encode['Vehicle'] = encode['Entity'];
|
||||
encode['Weapon'] = encode['Entity'];
|
||||
encode['NPC'] = encode['Entity'];
|
||||
encode['NextBot'] = encode['Entity'];
|
||||
|
||||
encode['nil'] = function()
|
||||
output[ #output + 1 ] = '?';
|
||||
end
|
||||
encode.__index = function( key )
|
||||
ErrorNoHalt('Type: '..key..' can not be encoded. Encoded as as pass-over value.');
|
||||
return encode['nil'];
|
||||
end
|
||||
|
||||
do
|
||||
local empty, concat = table.Empty, table.concat ;
|
||||
function pon1.encode( tbl )
|
||||
local output = {};
|
||||
cacheSize = 0;
|
||||
encode[ 'table' ]( encode, tbl, output, {} );
|
||||
local res = concat( output );
|
||||
|
||||
return res;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local tonumber = tonumber ;
|
||||
local find, sub, gsub, Explode = string.find, string.sub, string.gsub, string.Explode ;
|
||||
local Vector, Angle, Entity = Vector, Angle, Entity ;
|
||||
|
||||
local decode = {};
|
||||
decode['{'] = function( self, index, str, cache )
|
||||
|
||||
local cur = {};
|
||||
cache[ #cache + 1 ] = cur;
|
||||
|
||||
local k, v, tk, tv = 1, nil, nil, nil;
|
||||
while( true )do
|
||||
tv = sub( str, index, index );
|
||||
if( not tv or tv == '~' )then
|
||||
index = index + 1;
|
||||
break ;
|
||||
end
|
||||
if( tv == '}' )then
|
||||
return index + 1, cur;
|
||||
end
|
||||
|
||||
-- READ THE VALUE
|
||||
index = index + 1;
|
||||
index, v = self[ tv ]( self, index, str, cache );
|
||||
cur[ k ] = v;
|
||||
|
||||
k = k + 1;
|
||||
end
|
||||
|
||||
while( true )do
|
||||
tk = sub( str, index, index );
|
||||
if( not tk or tk == '}' )then
|
||||
index = index + 1;
|
||||
break ;
|
||||
end
|
||||
|
||||
-- READ THE KEY
|
||||
|
||||
index = index + 1;
|
||||
index, k = self[ tk ]( self, index, str, cache );
|
||||
|
||||
-- READ THE VALUE
|
||||
tv = sub( str, index, index );
|
||||
index = index + 1;
|
||||
index, v = self[ tv ]( self, index, str, cache );
|
||||
|
||||
cur[ k ] = v;
|
||||
end
|
||||
|
||||
return index, cur;
|
||||
end
|
||||
decode['['] = function( self, index, str, cache )
|
||||
|
||||
local cur = {};
|
||||
cache[ #cache + 1 ] = cur;
|
||||
|
||||
local k, v, tk, tv = 1, nil, nil, nil;
|
||||
while( true )do
|
||||
tk = sub( str, index, index );
|
||||
if( not tk or tk == '}' )then
|
||||
index = index + 1;
|
||||
break ;
|
||||
end
|
||||
|
||||
-- READ THE KEY
|
||||
index = index + 1;
|
||||
index, k = self[ tk ]( self, index, str, cache );
|
||||
if not k then continue end
|
||||
|
||||
-- READ THE VALUE
|
||||
tv = sub( str, index, index );
|
||||
index = index + 1;
|
||||
if not self[tv] then
|
||||
print('did not find type: '..tv)
|
||||
end
|
||||
index, v = self[ tv ]( self, index, str, cache );
|
||||
|
||||
cur[ k ] = v;
|
||||
end
|
||||
|
||||
return index, cur;
|
||||
end
|
||||
|
||||
-- STRING
|
||||
decode['"'] = function( self, index, str, cache )
|
||||
local finish = find( str, '";', index, true );
|
||||
local res = gsub( sub( str, index, finish - 1 ), '\\;', ';' );
|
||||
index = finish + 2;
|
||||
|
||||
cache[ #cache + 1 ] = res;
|
||||
return index, res;
|
||||
end
|
||||
-- STRING NO ESCAPING NEEDED
|
||||
decode['\''] = function( self, index, str, cache )
|
||||
local finish = find( str, ';', index, true );
|
||||
local res = sub( str, index, finish - 1 )
|
||||
index = finish + 1;
|
||||
|
||||
cache[ #cache + 1 ] = res;
|
||||
return index, res;
|
||||
end
|
||||
|
||||
-- NUMBER
|
||||
decode['n'] = function( self, index, str, cache )
|
||||
index = index - 1;
|
||||
local finish = find( str, ';', index, true );
|
||||
local num = tonumber( sub( str, index, finish - 1 ) );
|
||||
index = finish + 1;
|
||||
return index, num;
|
||||
end
|
||||
decode['0'] = decode['n'];
|
||||
decode['1'] = decode['n'];
|
||||
decode['2'] = decode['n'];
|
||||
decode['3'] = decode['n'];
|
||||
decode['4'] = decode['n'];
|
||||
decode['5'] = decode['n'];
|
||||
decode['6'] = decode['n'];
|
||||
decode['7'] = decode['n'];
|
||||
decode['8'] = decode['n'];
|
||||
decode['9'] = decode['n'];
|
||||
decode['-'] = decode['n'];
|
||||
-- positive hex
|
||||
decode['X'] = function( self, index, str, cache )
|
||||
local finish = find( str, ';', index, true );
|
||||
local num = tonumber( sub( str, index, finish - 1), 16 );
|
||||
index = finish + 1;
|
||||
return index, num;
|
||||
end
|
||||
-- negative hex
|
||||
decode['x'] = function( self, index, str, cache )
|
||||
local finish = find( str, ';', index, true );
|
||||
local num = -tonumber( sub( str, index, finish - 1), 16 );
|
||||
index = finish + 1;
|
||||
return index, num;
|
||||
end
|
||||
|
||||
-- POINTER
|
||||
decode['('] = function( self, index, str, cache )
|
||||
local finish = find( str, ')', index, true );
|
||||
local num = tonumber( sub( str, index, finish - 1), 16 );
|
||||
index = finish + 1;
|
||||
return index, cache[ num ];
|
||||
end
|
||||
|
||||
-- BOOLEAN. ONE DATA TYPE FOR YES, ANOTHER FOR NO.
|
||||
decode[ 't' ] = function( self, index )
|
||||
return index, true;
|
||||
end
|
||||
decode[ 'f' ] = function( self, index )
|
||||
return index, false;
|
||||
end
|
||||
|
||||
-- VECTOR
|
||||
decode[ 'v' ] = function( self, index, str, cache )
|
||||
local finish = find( str, ';', index, true );
|
||||
local vecStr = sub( str, index, finish - 1 );
|
||||
index = finish + 1; -- update the index.
|
||||
local segs = Explode( ',', vecStr, false );
|
||||
return index, Vector( tonumber( segs[1] ), tonumber( segs[2] ), tonumber( segs[3] ) );
|
||||
end
|
||||
-- ANGLE
|
||||
decode[ 'a' ] = function( self, index, str, cache )
|
||||
local finish = find( str, ';', index, true );
|
||||
local angStr = sub( str, index, finish - 1 );
|
||||
index = finish + 1; -- update the index.
|
||||
local segs = Explode( ',', angStr, false );
|
||||
return index, Angle( tonumber( segs[1] ), tonumber( segs[2] ), tonumber( segs[3] ) );
|
||||
end
|
||||
-- ENTITY
|
||||
decode[ 'E' ] = function( self, index, str, cache )
|
||||
if( str[index] == '#' )then
|
||||
index = index + 1;
|
||||
return index, NULL ;
|
||||
else
|
||||
local finish = find( str, ';', index, true );
|
||||
local num = tonumber( sub( str, index, finish - 1 ) );
|
||||
index = finish + 1;
|
||||
return index, Entity( num );
|
||||
end
|
||||
end
|
||||
-- PLAYER
|
||||
decode[ 'P' ] = function( self, index, str, cache )
|
||||
local finish = find( str, ';', index, true );
|
||||
local num = tonumber( sub( str, index, finish - 1 ) );
|
||||
index = finish + 1;
|
||||
return index, Entity( num ) or NULL;
|
||||
end
|
||||
-- NIL
|
||||
decode['?'] = function( self, index, str, cache )
|
||||
return index + 1, nil;
|
||||
end
|
||||
|
||||
|
||||
function pon1.decode( data )
|
||||
local _, res = decode[sub(data,1,1)]( decode, 2, data, {});
|
||||
return res;
|
||||
end
|
||||
end
|
||||
157
addons/plogs/lua/plogs/lib/ptmysql.lua
Normal file
157
addons/plogs/lua/plogs/lib/ptmysql.lua
Normal file
@@ -0,0 +1,157 @@
|
||||
local tostring = tostring;
|
||||
local pairs = pairs;
|
||||
local ipairs = ipairs;
|
||||
local string = string;
|
||||
local unpack = unpack;
|
||||
local SysTime = SysTime;
|
||||
|
||||
require( 'tmysql4' );
|
||||
|
||||
ptmysql = { };
|
||||
|
||||
local db_cache = { };
|
||||
local query_cache = { };
|
||||
local sync_timeout = 0.3;
|
||||
local logging_enabled = true;
|
||||
local log_file = 'pmysql_log.txt';
|
||||
local max_errors = 10;
|
||||
|
||||
local db_mt = { };
|
||||
db_mt.__index = db_mt;
|
||||
|
||||
function ptmysql.print( ... )
|
||||
return MsgC( Color( 225, 0, 0 ), '[MYSQL] ', Color( 255, 255, 255 ), ... .. '\n' );
|
||||
end
|
||||
|
||||
function ptmysql.log( str )
|
||||
ptmysql.print( str );
|
||||
if not logging_enabled then return end
|
||||
file.Append( log_file, os.date( '[%X - %d/%m/%Y] ', os.time() ) .. str .. '\n' );
|
||||
end
|
||||
|
||||
function ptmysql.connect( hostname, username, password, database, port, optional_unix_socket_path )
|
||||
local obj = { };
|
||||
setmetatable( obj, db_mt );
|
||||
|
||||
obj.hash = string.format( '%s:%s@%X:%s', hostname, port, util.CRC( username .. '-' .. password ), database );
|
||||
|
||||
if db_cache[ obj.hash ] then
|
||||
ptmysql.log( 'Recycled database connection : ' .. obj.database .. '-' .. obj.port );
|
||||
return db_cache[ obj.hash ]._db
|
||||
end
|
||||
|
||||
obj._db, obj.err = tmysql.initialize( hostname, username, password, database, port, optional_unix_socket_path );
|
||||
obj.hostname = hostname;
|
||||
obj.username = username;
|
||||
obj.password = password;
|
||||
obj.database = database;
|
||||
obj.port = port;
|
||||
|
||||
if obj._db then
|
||||
ptmysql.log( 'Connected to database ' .. database .. ':' .. port .. ' successfully.' );
|
||||
elseif obj.err then
|
||||
ptmysql.log( 'Connection to database ' .. database .. ':' .. port .. ' failed. ERROR: ' .. obj.err );
|
||||
return
|
||||
end
|
||||
|
||||
db_cache[ obj.hash ] = obj;
|
||||
|
||||
return obj;
|
||||
end
|
||||
ptmysql.newdb = ptmysql.connect;
|
||||
|
||||
function ptmysql.getTable( )
|
||||
return db_cache;
|
||||
end
|
||||
|
||||
function ptmysql.pollAll( )
|
||||
for _, db in pairs( ptmysql.getTable() ) do
|
||||
db:poll( );
|
||||
end
|
||||
end
|
||||
|
||||
function ptmysql.setTimeOut( time )
|
||||
sync_timeout = time;
|
||||
end
|
||||
|
||||
function ptmysql.setMaxErrors( num )
|
||||
max_errors = num;
|
||||
end
|
||||
|
||||
function ptmysql.enableLog( bool )
|
||||
logging_enabled = bool;
|
||||
end
|
||||
|
||||
function db_mt:escape( str )
|
||||
return self._db:Escape( tostring( str ) );
|
||||
end
|
||||
|
||||
function db_mt:poll( )
|
||||
return self._db:Poll( );
|
||||
end
|
||||
|
||||
function db_mt:setCharset( charset )
|
||||
return self._db:SetCharset( charset );
|
||||
end
|
||||
|
||||
function db_mt:disconnect( )
|
||||
self._db:Disconnect( );
|
||||
db_cache[ self ] = nil;
|
||||
end
|
||||
|
||||
function db_mt:query( sqlstr, cback )
|
||||
return self._db:Query( sqlstr, function( results )
|
||||
if results[1].error then
|
||||
ptmysql.log( self.database .. ':' .. self.port .. ' - ' .. results[1].error );
|
||||
if ( query_cache[ sqlstr ] == nil ) then
|
||||
query_cache[ sqlstr ] = { obj = self, cback = cback };
|
||||
elseif ( max_errors ~= nil ) and ( query_cache[ sqlstr ] ~= nil ) and ( query_cache[ sqlstr ].errcount >= max_errors ) then
|
||||
ptmysql.log( 'ERROR: Query timeout - ' .. sqlstr );
|
||||
query_cache[ sqlstr ] = nil;
|
||||
elseif ( query_cache[ sqlstr ] ~= nil ) then
|
||||
query_cache[ sqlstr ].retry = true;
|
||||
end
|
||||
else
|
||||
if cback then cback( results[1].data ); end
|
||||
end
|
||||
end, QUERY_FLAG_ASSOC );
|
||||
end
|
||||
|
||||
function db_mt:query_ex( sqlstr, options, cback )
|
||||
if options ~= nil then
|
||||
for k, v in ipairs( options ) do
|
||||
options[ k ] = self:escape( v );
|
||||
end
|
||||
|
||||
sqlstr = sqlstr:gsub( '%%','%%%%' ):gsub( '?', '%%s' );
|
||||
sqlstr = string.format( sqlstr, unpack( options ) );
|
||||
end
|
||||
return self:query( sqlstr, cback );
|
||||
end
|
||||
|
||||
function db_mt:query_sync( sqlstr, options, timeout )
|
||||
local _data;
|
||||
local done = false;
|
||||
local time = SysTime() + ( timeout and timeout or sync_timeout );
|
||||
self:query_ex( sqlstr, options, function( data )
|
||||
_data = data;
|
||||
done = true;
|
||||
time = 0;
|
||||
end );
|
||||
|
||||
while ( not done ) and ( time > SysTime() ) do
|
||||
self:poll( );
|
||||
end
|
||||
|
||||
return _data;
|
||||
end
|
||||
|
||||
hook.Add('Tick', 'ptmysql.Poll', function()
|
||||
for k, v in pairs( query_cache ) do
|
||||
if ( v.retry ~= false ) then
|
||||
v.errcount = ( v.errcount ~= nil ) and ( v.errcount + 1 ) or 2;
|
||||
v.retry = false;
|
||||
v.obj:query( k, v.cback );
|
||||
end
|
||||
end
|
||||
end );
|
||||
211
addons/plogs/lua/plogs/lib/sha2.lua
Normal file
211
addons/plogs/lua/plogs/lib/sha2.lua
Normal file
@@ -0,0 +1,211 @@
|
||||
-- Ported to glua from http://lua-users.org/wiki/SecureHashAlgorithm
|
||||
|
||||
sha2 = {}
|
||||
|
||||
local assert = assert
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local bit_band = bit.band
|
||||
local bit_ror = bit.ror
|
||||
local bit_bxor = bit.bxor
|
||||
local bit_rshift = bit.rshift
|
||||
local bit_bnot = bit.bnot
|
||||
|
||||
local string_gsub = string.gsub
|
||||
local string_format = string.format
|
||||
local string_byte = string.byte
|
||||
local string_rep = string.rep
|
||||
|
||||
|
||||
-- Initialize table of round constants
|
||||
-- (first 32 bits of the fractional parts of the cube roots of the first
|
||||
-- 64 primes 2..311):
|
||||
local k = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
||||
}
|
||||
|
||||
|
||||
-- transform a string of bytes in a string of hexadecimal digits
|
||||
local function str2hexa (s)
|
||||
return string_gsub(s, ".", function(c)
|
||||
return string_format("%02x", string_byte(c))
|
||||
end)
|
||||
end
|
||||
|
||||
-- transform number 'l' in a big-endian sequence of 'n' bytes
|
||||
-- (coded as a string)
|
||||
local function num2s (l, n)
|
||||
local s = ""
|
||||
for i = 1, n do
|
||||
local rem = l % 256
|
||||
s = string.char(rem) .. s
|
||||
l = (l - rem) / 256
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
-- transform the big-endian sequence of four bytes starting at
|
||||
-- index 'i' in 's' into a number
|
||||
local function s232num (s, i)
|
||||
local n = 0
|
||||
for i = i, i + 3 do
|
||||
n = n*256 + string_byte(s, i)
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
|
||||
-- append the bit '1' to the message
|
||||
-- append k bits '0', where k is the minimum number >= 0 such that the
|
||||
-- resulting message length (in bits) is congruent to 448 (mod 512)
|
||||
-- append length of message (before pre-processing), in bits, as 64-bit
|
||||
-- big-endian integer
|
||||
local function preproc (msg, len)
|
||||
local extra = -(len + 1 + 8) % 64
|
||||
len = num2s(8 * len, 8) -- original len in bits, coded
|
||||
msg = msg .. "\128" .. string_rep("\0", extra) .. len
|
||||
assert(#msg % 64 == 0)
|
||||
return msg
|
||||
end
|
||||
|
||||
local function initH224 (H)
|
||||
-- (second 32 bits of the fractional parts of the square roots of the
|
||||
-- 9th through 16th primes 23..53)
|
||||
H[1] = 0xc1059ed8
|
||||
H[2] = 0x367cd507
|
||||
H[3] = 0x3070dd17
|
||||
H[4] = 0xf70e5939
|
||||
H[5] = 0xffc00b31
|
||||
H[6] = 0x68581511
|
||||
H[7] = 0x64f98fa7
|
||||
H[8] = 0xbefa4fa4
|
||||
return H
|
||||
end
|
||||
|
||||
|
||||
local function initH256 (H)
|
||||
-- (first 32 bits of the fractional parts of the square roots of the
|
||||
-- first 8 primes 2..19):
|
||||
H[1] = 0x6a09e667
|
||||
H[2] = 0xbb67ae85
|
||||
H[3] = 0x3c6ef372
|
||||
H[4] = 0xa54ff53a
|
||||
H[5] = 0x510e527f
|
||||
H[6] = 0x9b05688c
|
||||
H[7] = 0x1f83d9ab
|
||||
H[8] = 0x5be0cd19
|
||||
return H
|
||||
end
|
||||
|
||||
|
||||
local function digestblock (msg, i, H)
|
||||
|
||||
-- break chunk into sixteen 32-bit big-endian words w[1..16]
|
||||
local w = {}
|
||||
for j = 1, 16 do
|
||||
w[j] = s232num(msg, i + (j - 1)*4)
|
||||
end
|
||||
|
||||
-- Extend the sixteen 32-bit words into sixty-four 32-bit words:
|
||||
for j = 17, 64 do
|
||||
local v = w[j - 15]
|
||||
local s0 = bit_bxor(bit_ror(v, 7), bit_ror(v, 18), bit_rshift(v, 3))
|
||||
v = w[j - 2]
|
||||
local s1 = bit_bxor(bit_ror(v, 17), bit_ror(v, 19), bit_rshift(v, 10))
|
||||
w[j] = w[j - 16] + s0 + w[j - 7] + s1
|
||||
end
|
||||
|
||||
-- Initialize hash value for this chunk:
|
||||
local a, b, c, d, e, f, g, h =
|
||||
H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
|
||||
|
||||
-- Main loop:
|
||||
for i = 1, 64 do
|
||||
local s0 = bit_bxor(bit_ror(a, 2), bit_ror(a, 13), bit_ror(a, 22))
|
||||
local maj = bit_bxor(bit_band(a, b), bit_band(a, c), bit_band(b, c))
|
||||
local t2 = s0 + maj
|
||||
local s1 = bit_bxor(bit_ror(e, 6), bit_ror(e, 11), bit_ror(e, 25))
|
||||
local ch = bit_bxor (bit_band(e, f), bit_band(bit_bnot(e), g))
|
||||
local t1 = h + s1 + ch + k[i] + w[i]
|
||||
|
||||
h = g
|
||||
g = f
|
||||
f = e
|
||||
e = d + t1
|
||||
d = c
|
||||
c = b
|
||||
b = a
|
||||
a = t1 + t2
|
||||
end
|
||||
|
||||
-- Add (mod 2^32) this chunk's hash to result so far:
|
||||
H[1] = bit_band(H[1] + a)
|
||||
H[2] = bit_band(H[2] + b)
|
||||
H[3] = bit_band(H[3] + c)
|
||||
H[4] = bit_band(H[4] + d)
|
||||
H[5] = bit_band(H[5] + e)
|
||||
H[6] = bit_band(H[6] + f)
|
||||
H[7] = bit_band(H[7] + g)
|
||||
H[8] = bit_band(H[8] + h)
|
||||
|
||||
end
|
||||
|
||||
|
||||
local function finalresult224 (H)
|
||||
-- Produce the final hash value (big-endian):
|
||||
return
|
||||
str2hexa(num2s(H[1], 4)..num2s(H[2], 4)..num2s(H[3], 4)..num2s(H[4], 4)..
|
||||
num2s(H[5], 4)..num2s(H[6], 4)..num2s(H[7], 4))
|
||||
end
|
||||
|
||||
|
||||
local function finalresult256 (H)
|
||||
-- Produce the final hash value (big-endian):
|
||||
return
|
||||
str2hexa(num2s(H[1], 4)..num2s(H[2], 4)..num2s(H[3], 4)..num2s(H[4], 4)..
|
||||
num2s(H[5], 4)..num2s(H[6], 4)..num2s(H[7], 4)..num2s(H[8], 4))
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
local HH = {} -- to reuse
|
||||
|
||||
function sha2.hash224 (msg)
|
||||
msg = preproc(msg, #msg)
|
||||
local H = initH224(HH)
|
||||
|
||||
-- Process the message in successive 512-bit (64 bytes) chunks:
|
||||
for i = 1, #msg, 64 do
|
||||
digestblock(msg, i, H)
|
||||
end
|
||||
|
||||
return finalresult224(H)
|
||||
end
|
||||
|
||||
|
||||
function sha2.hash256 (msg)
|
||||
msg = preproc(msg, #msg)
|
||||
local H = initH256(HH)
|
||||
|
||||
-- Process the message in successive 512-bit (64 bytes) chunks:
|
||||
for i = 1, #msg, 64 do
|
||||
digestblock(msg, i, H)
|
||||
end
|
||||
|
||||
return finalresult256(H)
|
||||
end
|
||||
23
addons/plogs/lua/plogs/lib/table.lua
Normal file
23
addons/plogs/lua/plogs/lib/table.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
function table.Filter(tab, func)
|
||||
local c = 1
|
||||
for i = 1, #tab do
|
||||
if func(tab[i]) then
|
||||
tab[c] = tab[i]
|
||||
c = c + 1
|
||||
end
|
||||
end
|
||||
for i = c, #tab do
|
||||
tab[i] = nil
|
||||
end
|
||||
return tab
|
||||
end
|
||||
|
||||
function table.FilterCopy(tab, func)
|
||||
local ret = {}
|
||||
for i = 1, #tab do
|
||||
if func(tab[i]) then
|
||||
ret[#ret + 1] = tab[i]
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
331
addons/plogs/lua/plogs/menu.lua
Normal file
331
addons/plogs/lua/plogs/menu.lua
Normal file
@@ -0,0 +1,331 @@
|
||||
-- To-do recode this mess.
|
||||
surface.CreateFont('plogs.ui.26', {font = 'roboto', size = 26, weight = 400})
|
||||
surface.CreateFont('plogs.ui.24', {font = 'roboto', size = 24, weight = 400})
|
||||
surface.CreateFont('plogs.ui.22', {font = 'roboto', size = 22, weight = 400})
|
||||
surface.CreateFont('plogs.ui.20', {font = 'roboto', size = 20, weight = 400})
|
||||
surface.CreateFont('plogs.ui.19', {font = 'roboto', size = 19, weight = 400})
|
||||
surface.CreateFont('plogs.ui.18', {font = 'roboto', size = 18, weight = 400})
|
||||
surface.CreateFont('plogs.ui.16', {font = 'roboto', size = 16, weight = 400})
|
||||
|
||||
local function Search(command)
|
||||
local w, h = ScrW() * .3, 120
|
||||
local posx, posy = ScrW()/2 - w/2, ScrH()/2 - h/2
|
||||
|
||||
if IsValid(plogs.SearchMenu) then
|
||||
plogs.SearchMenu:Remove()
|
||||
end
|
||||
|
||||
if IsValid(plogs.Menu) then
|
||||
local x, y = plogs.Menu:GetPos()
|
||||
posy = plogs.Menu:GetTall() + y + 10
|
||||
end
|
||||
|
||||
local fr = vgui.Create('plogs_frame')
|
||||
fr:SetTitle('Search')
|
||||
fr:SetSize(w, h)
|
||||
fr:SetPos(posx, posy)
|
||||
plogs.SearchMenu = fr
|
||||
|
||||
local lbl = vgui.Create('DLabel', fr)
|
||||
lbl:SetPos(5, 35)
|
||||
lbl:SetText('Enter a SteamID to search')
|
||||
lbl:SetFont('plogs.ui.20')
|
||||
lbl:SetTextColor(plogs.ui.Close)
|
||||
lbl:SizeToContents()
|
||||
|
||||
local txt = vgui.Create('DTextEntry', fr)
|
||||
txt:SetPos(5, 60)
|
||||
txt:SetSize(w - 10, 25)
|
||||
txt:SetFont('plogs.ui.22')
|
||||
|
||||
local srch = vgui.Create('DButton', fr)
|
||||
srch:SetPos(5, 90)
|
||||
srch:SetSize(w - 10, 25)
|
||||
srch:SetText('Search')
|
||||
srch.DoClick = function(self)
|
||||
LocalPlayer():ConCommand('plogs "' .. command .. '" "' .. txt:GetValue() .. '"')
|
||||
fr:Close()
|
||||
end
|
||||
end
|
||||
|
||||
local function LogMenu(title, data)
|
||||
if IsValid(plogs.Menu) then
|
||||
plogs.Menu:SetVisible(false)
|
||||
end
|
||||
if IsValid(plogs.LogMenu) then
|
||||
plogs.LogMenu:Remove()
|
||||
end
|
||||
|
||||
local w, h = plogs.cfg.Width * ScrW(), plogs.cfg.Height * ScrH()
|
||||
|
||||
local fr = vgui.Create('plogs_frame')
|
||||
fr:SetTitle('Search')
|
||||
fr:SetSize(w, h)
|
||||
fr:SetTitle(title)
|
||||
fr:Center()
|
||||
fr._Close = fr.Close
|
||||
fr.Close = function(self)
|
||||
if IsValid(plogs.Menu) then
|
||||
plogs.Menu:SetVisible(true)
|
||||
end
|
||||
fr:_Close()
|
||||
end
|
||||
plogs.LogMenu = fr
|
||||
|
||||
local logList = vgui.Create('DListView', fr)
|
||||
logList:SetPos(0, 29)
|
||||
logList:SetSize(fr:GetWide(), fr:GetTall() - 29)
|
||||
logList:SetMultiSelect(false)
|
||||
logList:AddColumn('Date'):SetFixedWidth(175)
|
||||
logList:AddColumn('Data')
|
||||
logList.OnRowSelected = function(parent, line)
|
||||
local column = logList:GetLine(line)
|
||||
local log = column:GetColumnText(2)
|
||||
local menu = DermaMenu()
|
||||
|
||||
menu:SetSkin('pLogs')
|
||||
menu:AddOption('Copy Line', function()
|
||||
SetClipboardText(log)
|
||||
LocalPlayer():ChatPrint('Copied Line')
|
||||
end)
|
||||
menu:Open()
|
||||
end
|
||||
|
||||
for k, v in ipairs(data) do
|
||||
logList:AddLine(isstring(v.Date) and v.Date or os.date('%X - %d/%m/%Y', v.Date), v.Data)
|
||||
end
|
||||
end
|
||||
|
||||
local c = 1
|
||||
local saveList
|
||||
local function OpenMenu()
|
||||
local w, h = plogs.cfg.Width * ScrW(), plogs.cfg.Height * ScrH()
|
||||
c = 1
|
||||
|
||||
local fr = plogs.Menu
|
||||
|
||||
if IsValid(fr) then
|
||||
fr:Remove()
|
||||
end
|
||||
|
||||
local count = table.Count(plogs.data)
|
||||
local fr = vgui.Create('plogs_frame')
|
||||
fr:SetSize(w, h)
|
||||
fr:Center()
|
||||
fr._Close = fr.Close
|
||||
fr.Close = function(self)
|
||||
if IsValid(plogs.SearchMenu) then
|
||||
plogs.SearchMenu:Close()
|
||||
end
|
||||
fr:_Close()
|
||||
end
|
||||
fr.PaintOver = function(self, w, h)
|
||||
if (c < count) then
|
||||
plogs.draw.Box(0, 0, w * c/count , 4, plogs.ui.ProgressBar)
|
||||
end
|
||||
end
|
||||
plogs.Menu = fr
|
||||
|
||||
local tabs = vgui.Create('plogs_tablist', fr)
|
||||
tabs:SetPos(0, 29)
|
||||
tabs:SetSize(w, h - 29)
|
||||
plogs.Menu.Tabs = tabs
|
||||
|
||||
local pnl = vgui.Create('DPanel', tabs)
|
||||
tabs:AddTab('Saves', pnl, true)
|
||||
|
||||
local logList = vgui.Create('DListView', pnl)
|
||||
logList:SetPos(0, 0)
|
||||
logList:SetSize(pnl:GetWide(), pnl:GetTall() - 150)
|
||||
logList:SetMultiSelect(false)
|
||||
logList:AddColumn('Time'):SetFixedWidth(75)
|
||||
logList:AddColumn('Data')
|
||||
logList.OnRowSelected = function(parent, line)
|
||||
local column = logList:GetLine(line)
|
||||
local log = column:GetColumnText(2)
|
||||
local menu = DermaMenu()
|
||||
|
||||
menu:SetSkin('pLogs')
|
||||
menu:AddOption('Copy Line', function()
|
||||
SetClipboardText(log)
|
||||
LocalPlayer():ChatPrint('Copied Line')
|
||||
end)
|
||||
for name, value in SortedPairs(column.Copy or {}) do
|
||||
menu:AddOption('Copy ' .. name, function()
|
||||
SetClipboardText(value or 'ERROR')
|
||||
LocalPlayer():ChatPrint('Copied ' .. name)
|
||||
end)
|
||||
end
|
||||
menu:Open()
|
||||
end
|
||||
logList.AddLogs = function(self, name)
|
||||
for k, v in pairs(self:GetLines()) do
|
||||
self:RemoveLine(k)
|
||||
end
|
||||
for _, log in SortedPairs(plogs.OpenSave(name)) do
|
||||
local line = self:AddLine(log.Date, log.Data)
|
||||
line.Copy = log.Copy
|
||||
end
|
||||
end
|
||||
|
||||
local save
|
||||
saveList = vgui.Create('DListView', pnl)
|
||||
saveList:SetPos(5, pnl:GetTall() - 145)
|
||||
saveList:SetSize(pnl:GetWide()/2 - 7.5, 140)
|
||||
saveList:SetMultiSelect(false)
|
||||
saveList:AddColumn('Saves')
|
||||
saveList.OnRowSelected = function(parent, line)
|
||||
save = saveList:GetLine(line):GetColumnText(1)
|
||||
end
|
||||
saveList.AddSaves = function(self)
|
||||
for k, v in pairs(self:GetLines()) do
|
||||
self:RemoveLine(k)
|
||||
end
|
||||
for k, v in ipairs(plogs.GetSaves()) do
|
||||
self:AddLine(v)
|
||||
if (k == 1) then save = v end
|
||||
end
|
||||
end
|
||||
saveList:AddSaves()
|
||||
|
||||
local btn = vgui.Create('DButton', pnl)
|
||||
btn:SetPos(pnl:GetWide()/2 + 2.25, pnl:GetTall() - 145)
|
||||
btn:SetSize(pnl:GetWide()/2 - 7.5, 25)
|
||||
btn:SetText('Open')
|
||||
btn.DoClick = function()
|
||||
logList:AddLogs(save)
|
||||
end
|
||||
|
||||
btn = vgui.Create('DButton', pnl)
|
||||
btn:SetPos(pnl:GetWide()/2 + 2.25, pnl:GetTall() - 115)
|
||||
btn:SetSize(pnl:GetWide()/2 - 7.5, 25)
|
||||
btn:SetText('Delete')
|
||||
btn.DoClick = function()
|
||||
plogs.DeleteSave(save)
|
||||
saveList:AddSaves()
|
||||
end
|
||||
|
||||
if plogs.cfg.EnableMySQL then
|
||||
tabs:AddButton('Player Events', function()
|
||||
Search('playerevents')
|
||||
end)
|
||||
|
||||
if plogs.cfg.IPUserGroups[string.lower(LocalPlayer():GetUserGroup())] then
|
||||
tabs:AddButton('IP logs', function()
|
||||
Search('ipsearch')
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
net.Receive('plogs.OpenMenu', function()
|
||||
if (not IsValid(plogs.Menu)) then OpenMenu() end
|
||||
|
||||
local name = net.ReadString()
|
||||
local size = net.ReadUInt(16)
|
||||
local data = plogs.Decode(net.ReadData(size))
|
||||
|
||||
plogs.data[name] = data
|
||||
|
||||
local tabs = plogs.Menu.Tabs
|
||||
local pnl = vgui.Create('DPanel', tabs)
|
||||
tabs:AddTab(name, pnl)
|
||||
|
||||
local lbl = Label('Search:', pnl)
|
||||
lbl:SetFont('plogs.ui.22')
|
||||
lbl:SetTextColor(plogs.ui.Close)
|
||||
lbl:SetPos(5, pnl:GetTall() - 28)
|
||||
|
||||
local txt = vgui.Create('DTextEntry', pnl)
|
||||
txt:SetPos(75, pnl:GetTall() - 30)
|
||||
txt:SetSize(pnl:GetWide() - 145, 25)
|
||||
txt:SetFont('plogs.ui.22')
|
||||
|
||||
local save = vgui.Create('DButton', pnl)
|
||||
save:SetPos(pnl:GetWide() - 65, pnl:GetTall() - 30)
|
||||
save:SetSize(60, 25)
|
||||
save:SetText('Save')
|
||||
save.DoClick = function()
|
||||
Derma_StringRequest('Save Log', 'What do you want to name this save?', '', function(name)
|
||||
if (#pnl.Data == 0) then
|
||||
LocalPlayer():ChatPrint('There are no results to save!')
|
||||
else
|
||||
plogs.SaveLog(name, pnl.Data)
|
||||
LocalPlayer():ChatPrint('Saved Log')
|
||||
end
|
||||
if IsValid(saveList) then saveList:AddSaves() end
|
||||
end,
|
||||
function(text)
|
||||
end)--:SetSkin('pLogs')
|
||||
end
|
||||
|
||||
local logList = vgui.Create('DListView', pnl)
|
||||
logList:SetPos(0, 0)
|
||||
logList:SetSize(pnl:GetWide(), pnl:GetTall() - 35)
|
||||
logList:SetMultiSelect(false)
|
||||
logList:AddColumn('Time'):SetFixedWidth(75)
|
||||
logList:AddColumn('Data')
|
||||
logList.OnRowSelected = function(parent, line)
|
||||
local column = logList:GetLine(line)
|
||||
local log = column:GetColumnText(2)
|
||||
local menu = DermaMenu()
|
||||
|
||||
menu:SetSkin('pLogs')
|
||||
menu:AddOption('Copy Line', function()
|
||||
SetClipboardText(log)
|
||||
LocalPlayer():ChatPrint('Copied Line')
|
||||
end)
|
||||
for name, value in SortedPairs(column.Copy or {}) do
|
||||
menu:AddOption('Copy ' .. name, function()
|
||||
SetClipboardText(value or 'ERROR')
|
||||
LocalPlayer():ChatPrint('Copied ' .. name)
|
||||
end)
|
||||
end
|
||||
menu:Open()
|
||||
end
|
||||
logList.LastSearch = ''
|
||||
pnl.Data = {}
|
||||
logList.Clear = function(self)
|
||||
for k, v in pairs(self:GetLines()) do
|
||||
self:RemoveLine(k)
|
||||
end
|
||||
pnl.Data = {}
|
||||
end
|
||||
logList.AddLogs = function(self)
|
||||
for _, log in SortedPairs(data) do
|
||||
local line = self:AddLine(log.Date, log.Data)
|
||||
line.Copy = log.Copy
|
||||
pnl.Data[#pnl.Data + 1] = log
|
||||
end
|
||||
end
|
||||
logList.Search = function(self, find)
|
||||
for _, log in SortedPairs(data) do
|
||||
if string.find(string.lower(log.Data), string.lower(find), 1, true) then
|
||||
local line = self:AddLine(log.Date, log.Data)
|
||||
line.Copy = log.Copy
|
||||
pnl.Data[#pnl.Data + 1] = log
|
||||
end
|
||||
end
|
||||
end
|
||||
logList.Think = function(self)
|
||||
local tosearch = string.Trim(txt:GetValue())
|
||||
if (tosearch ~= '') and (tosearch ~= self.LastSearch) then
|
||||
self:Clear()
|
||||
self:Search(tosearch)
|
||||
self.LastSearch = tosearch
|
||||
elseif (tosearch == '') and (tosearch ~= self.LastSearch) then
|
||||
self:Clear()
|
||||
self:AddLogs()
|
||||
self.LastSearch = tosearch
|
||||
end
|
||||
end
|
||||
logList:AddLogs()
|
||||
c = c + 1
|
||||
end)
|
||||
|
||||
net.Receive('plogs.LogData', function()
|
||||
local title = net.ReadString()
|
||||
local size = net.ReadUInt(16)
|
||||
local data = plogs.Decode(net.ReadData(size))
|
||||
LogMenu(title, data)
|
||||
end)
|
||||
41
addons/plogs/lua/plogs/mysql.lua
Normal file
41
addons/plogs/lua/plogs/mysql.lua
Normal file
@@ -0,0 +1,41 @@
|
||||
plogs.sql._db = plogs.sql._db or plogs.sql.newdb(plogs.cfg.IP , plogs.cfg.User, plogs.cfg.Pass, plogs.cfg.DB, plogs.cfg.Port)
|
||||
|
||||
local db = plogs.sql._db
|
||||
|
||||
function plogs.sql.LogIP(steamid64, ip, callback)
|
||||
return db:query_ex('REPLACE INTO ip_log(SteamID64, Data, Date) VALUES(?, "?", ' .. os.time() .. ');', {steamid64, ip}, callback)
|
||||
end
|
||||
|
||||
function plogs.sql.Log(steamid64, data, callback)
|
||||
return db:query_ex('INSERT INTO playerevents(SteamID64, Date, Data) VALUES(?, ' .. os.time() .. ', "?");', {steamid64, data}, callback)
|
||||
end
|
||||
|
||||
function plogs.sql.LoadIPs(steamid64, callback)
|
||||
return db:query_ex('SELECT * FROM ip_log WHERE SteamID64=?;', {steamid64}, callback)
|
||||
end
|
||||
|
||||
function plogs.sql.LoadLogs(steamid64, callback)
|
||||
return db:query_ex('SELECT * FROM playerevents WHERE SteamID64=? ORDER BY Date DESC LIMIT ' .. plogs.cfg.LogLimit .. ';', {steamid64}, callback)
|
||||
end
|
||||
|
||||
hook.Add('InitPostEntity', 'plogs.SQL.InitPostEntity', function()
|
||||
db:query_sync([[
|
||||
CREATE TABLE IF NOT EXISTS `ip_log` (
|
||||
`SteamID64` BIGINT(20) NOT NULL,
|
||||
`Data` VARCHAR(50) NOT NULL,
|
||||
`Date` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`SteamID64`, `Data`)
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=MyISAM;
|
||||
]])
|
||||
db:query_sync([[
|
||||
CREATE TABLE IF NOT EXISTS `playerevents` (
|
||||
`SteamID64` BIGINT(20) NOT NULL,
|
||||
`Date` INT(11) NOT NULL,
|
||||
`Data` TEXT NOT NULL
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=MyISAM;
|
||||
]])
|
||||
end)
|
||||
67
addons/plogs/lua/plogs/vgui/frame.lua
Normal file
67
addons/plogs/lua/plogs/vgui/frame.lua
Normal file
@@ -0,0 +1,67 @@
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.btnMaxim:Remove()
|
||||
self.btnMinim:Remove()
|
||||
|
||||
self.lblTitle:SetText('pLogs')
|
||||
self.lblTitle:SetColor(plogs.ui.Close)
|
||||
self.lblTitle:SetFont('plogs.ui.22')
|
||||
|
||||
self:SetSkin('pLogs')
|
||||
self:SetDraggable(true)
|
||||
self:MakePopup()
|
||||
|
||||
self:SetAlpha(0)
|
||||
self:FadeIn(0.2)
|
||||
|
||||
hook.Add('Think', self, function()
|
||||
if (self.animation) then
|
||||
self.animation:Run()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function PANEL:FadeIn(speed, cback)
|
||||
self.animation = Derma_Anim('Fade Panel', self, function(panel, animation, delta, data)
|
||||
panel:SetAlpha(delta * 255)
|
||||
if (animation.Finished) then
|
||||
self.animation = nil
|
||||
if cback then cback() end
|
||||
end
|
||||
end)
|
||||
if (self.animation) then
|
||||
self.animation:Start(speed)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:FadeOut(speed, cback)
|
||||
self.animation = Derma_Anim('Fade Panel', self, function(panel, animation, delta, data)
|
||||
panel:SetAlpha(255 - (delta * 255))
|
||||
if (animation.Finished) then
|
||||
self.animation = nil
|
||||
if cback then cback() end
|
||||
end
|
||||
end)
|
||||
if (self.animation) then
|
||||
self.animation:Start(speed)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self.lblTitle:SizeToContents()
|
||||
self.lblTitle:SetPos(5, 3)
|
||||
|
||||
self.btnClose:SetPos(self:GetWide() - 30, 0)
|
||||
self.btnClose:SetSize(30, 30)
|
||||
end
|
||||
|
||||
function PANEL:Close(cback)
|
||||
self.Think = function() end
|
||||
self:FadeOut(0.2, function()
|
||||
self:Remove()
|
||||
if cback then cback() end
|
||||
end)
|
||||
end
|
||||
|
||||
vgui.Register('plogs_frame', PANEL, 'DFrame')
|
||||
226
addons/plogs/lua/plogs/vgui/skin.lua
Normal file
226
addons/plogs/lua/plogs/vgui/skin.lua
Normal file
@@ -0,0 +1,226 @@
|
||||
local surface = surface
|
||||
local draw = draw
|
||||
|
||||
local SKIN = {}
|
||||
|
||||
SKIN.PrintName = 'pLogs'
|
||||
SKIN.Author = 'aStonedPenguin'
|
||||
|
||||
if plogs.cfg.DarkUI then
|
||||
-- Not finished
|
||||
SKIN.Background = Color(10,10,10,200)
|
||||
SKIN.Header = Color(25,25,25,225)
|
||||
SKIN.Outline = Color(0,0,0)
|
||||
|
||||
SKIN.Panel = Color(10,10,10,100)
|
||||
|
||||
SKIN.Button = Color(10,10,10,175)
|
||||
SKIN.ButtonHovered = Color(50,50,50,170)
|
||||
SKIN.ButtonText = Color(245,245,245)
|
||||
|
||||
SKIN.Close = SKIN.ButtonText
|
||||
SKIN.CloseHovered = Color(255,0,0)
|
||||
|
||||
SKIN.TabButton = SKIN.Header
|
||||
|
||||
SKIN.TextEntry = SKIN.Button
|
||||
SKIN.TextEntryOutline = SKIN.Outline
|
||||
SKIN.TextEntryText = SKIN.ButtonText
|
||||
SKIN.TextEntryHighlight = Color(51,128,255,200)
|
||||
|
||||
SKIN.ListBackground = SKIN.TextEntry
|
||||
SKIN.ListViewLine = SKIN.Button
|
||||
SKIN.ListViewLineAlt = SKIN.ButtonHovered
|
||||
SKIN.ListViewLineHighlight = SKIN.TextEntryHighlight
|
||||
SKIN.ListViewText = SKIN.ButtonText
|
||||
|
||||
else
|
||||
|
||||
SKIN.Background = Color(245,245,235,170)
|
||||
SKIN.Header = Color(230,230,220,225)
|
||||
SKIN.Outline = Color(170,170,170)
|
||||
|
||||
SKIN.Panel = Color(245,245,235,100)
|
||||
|
||||
SKIN.Button = Color(230,230,220)
|
||||
SKIN.ButtonHovered = Color(200,200,190)
|
||||
|
||||
SKIN.Close = Color(0,0,0)
|
||||
SKIN.CloseHovered = Color(255,0,0)
|
||||
|
||||
SKIN.TabButton = SKIN.Header
|
||||
|
||||
SKIN.TextEntry = SKIN.Button
|
||||
SKIN.TextEntryOutline = SKIN.Outline
|
||||
SKIN.TextEntryText = Color(0,0,0)
|
||||
SKIN.TextEntryHighlight = SKIN.ButtonHovered
|
||||
|
||||
SKIN.ListBackground = SKIN.TextEntry
|
||||
SKIN.ListViewLine = SKIN.Button
|
||||
SKIN.ListViewLineAlt = SKIN.ButtonHovered
|
||||
SKIN.ListViewLineHighlight = Color(200,0,0,200)
|
||||
SKIN.ListViewText = SKIN.ButtonText
|
||||
SKIN.ProgressBar = Color(225,0,0)
|
||||
end
|
||||
|
||||
plogs.ui = SKIN
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Frames
|
||||
----------------------------------------------------------------
|
||||
function SKIN:PaintFrame(self, w, h)
|
||||
plogs.draw.Blur(self)
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, SKIN.Background, SKIN.Outline)
|
||||
plogs.draw.OutlinedBox(0, 0, w, 30, SKIN.Header, SKIN.Outline)
|
||||
end
|
||||
|
||||
function SKIN:PaintPanel(self, w, h)
|
||||
if not (self.m_bBackground) then return end
|
||||
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, SKIN.Panel, SKIN.Outline)
|
||||
end
|
||||
|
||||
function SKIN:PaintShadow() end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Buttons
|
||||
----------------------------------------------------------------
|
||||
function SKIN:PaintButton(self, w, h)
|
||||
if not (self.m_bBackground) then return end
|
||||
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, self.Hovered and SKIN.ButtonHovered or SKIN.Button, SKIN.Outline)
|
||||
|
||||
if not self.fontset then
|
||||
self:SetTextColor(SKIN.Close)
|
||||
self:SetFont('plogs.ui.20')
|
||||
self.fontset = true
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Close Button
|
||||
----------------------------------------------------------------
|
||||
function SKIN:PaintWindowCloseButton(panel, w, h)
|
||||
if not (panel.m_bBackground) then return end
|
||||
|
||||
draw.SimpleText('x', 'plogs.ui.26', 11, 0, (self.Hovered and SKIN.CloseHovered or SKIN.Close), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Text Entry
|
||||
----------------------------------------------------------------
|
||||
function SKIN:PaintTextEntry(self, w, h)
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, SKIN.TextEntry, SKIN.TextEntryOutline)
|
||||
|
||||
self:DrawTextEntryText(SKIN.TextEntryText, SKIN.TextEntryHighlight, SKIN.TextEntryText)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- List View
|
||||
----------------------------------------------------------------
|
||||
function SKIN:PaintListView(self, w, h)
|
||||
--plogs.draw.Box(0, 0, w, h, SKIN.ListBackground)
|
||||
end
|
||||
|
||||
function SKIN:PaintListViewLine(self, w, h)
|
||||
local col = ((self:IsSelected() or self:IsHovered()) and SKIN.ListViewLineHighlight or SKIN.ListViewLine)
|
||||
|
||||
plogs.draw.Box(0, 0, w, h, ((self.m_bAlt and not (self:IsSelected() or self:IsHovered())) and SKIN.ListViewLineAlt or col))
|
||||
|
||||
for k, v in ipairs(self.Columns) do
|
||||
if (self:IsSelected() or self:IsHovered()) then
|
||||
|
||||
v:SetFont('plogs.ui.18')
|
||||
v:SetTextColor(SKIN.ListViewTextHighlight)
|
||||
else
|
||||
v:SetFont('plogs.ui.16')
|
||||
v:SetTextColor(SKIN.ListViewText)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Scrollbar --
|
||||
----------------------------------------------------------------
|
||||
function SKIN:PaintScrollBarGrip(self, w, h)
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, self.Hovered and SKIN.ButtonHovered or SKIN.Button, SKIN.Outline)
|
||||
end
|
||||
SKIN.PaintButtonDown = SKIN.PaintScrollBarGrip
|
||||
SKIN.PaintButtonUp = SKIN.PaintScrollBarGrip
|
||||
|
||||
function SKIN:PaintScrollPanel(self, w, h) end
|
||||
function SKIN:PaintVScrollBar(self, w, h) end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- Tabs
|
||||
----------------------------------------------------------------
|
||||
/*
|
||||
function SKIN:PaintTabListPanel(self, w, h)
|
||||
surface.SetDrawColor(SKIN.Outline)
|
||||
surface.DrawOutlinedRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
SKIN.PaintTabPanel = SKIN.PaintTabListPanel
|
||||
*/
|
||||
function SKIN:PaintTabListButton(self, w, h)
|
||||
if (self.Active or self.Hovered) then
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, SKIN.TabButton, SKIN.Outline)
|
||||
if self.Hovered then
|
||||
plogs.draw.Box(1, 1, 6, h - 2, SKIN.ProgressBar)
|
||||
else
|
||||
plogs.draw.Box(1, 1, 3, h - 2, SKIN.ProgressBar)
|
||||
end
|
||||
else
|
||||
plogs.draw.Outline(0, 0, w, h, SKIN.Outline)
|
||||
end
|
||||
self:SetTextColor(SKIN.Close)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- ComboBox
|
||||
----------------------------------------------------------------
|
||||
function SKIN:PaintComboBox(self, w, h)
|
||||
if IsValid(self.Menu) and not self.Menu.SkinSet then
|
||||
self.Menu:SetSkin('pLogs')
|
||||
self.Menu.SkinSet = true
|
||||
end
|
||||
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, ((self.Hovered or self.Depressed or self:IsMenuOpen()) and SKIN.ButtonHovered or SKIN.Button), SKIN.Outline)
|
||||
end
|
||||
|
||||
function SKIN:PaintComboDownArrow(self, w, h)
|
||||
surface.SetDrawColor(SKIN.ListViewLineHighlight)
|
||||
draw.NoTexture()
|
||||
surface.DrawPoly({
|
||||
{x = 0, y = w * .5},
|
||||
{x = h, y = 0},
|
||||
{x = h, y = w}
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- DMenu
|
||||
----------------------------------------------------------------
|
||||
function SKIN:PaintMenu(self, w, h)
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, SKIN.Button, SKIN.Outline)
|
||||
end
|
||||
|
||||
function SKIN:PaintMenuOption(self, w, h)
|
||||
if not self.FontSet then
|
||||
self:SetFont('plogs.ui.20')
|
||||
self:SetTextInset(5, 0)
|
||||
self.FontSet = true
|
||||
end
|
||||
|
||||
self:SetTextColor(SKIN.Close)
|
||||
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, SKIN.Button, SKIN.Outline)
|
||||
|
||||
if self.m_bBackground and (self.Hovered or self.Highlight) then
|
||||
plogs.draw.OutlinedBox(0, 0, w, h, SKIN.ButtonHovered , SKIN.Outline)
|
||||
end
|
||||
end
|
||||
|
||||
derma.DefineSkin('pLogs', 'pLogs\'s derma skin', SKIN)
|
||||
79
addons/plogs/lua/plogs/vgui/tablist.lua
Normal file
79
addons/plogs/lua/plogs/vgui/tablist.lua
Normal file
@@ -0,0 +1,79 @@
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.num = 0
|
||||
self:SetSkin('pLogs')
|
||||
self.tablist = vgui.Create('DScrollPanel', self)
|
||||
end
|
||||
|
||||
function PANEL:AddTab(title, tab, active)
|
||||
if active then
|
||||
self.CurrentTab = tab
|
||||
else
|
||||
tab:SetVisible(false)
|
||||
end
|
||||
|
||||
if (tab:GetParent() ~= self) then
|
||||
tab:SetParent(self)
|
||||
tab:SetSkin(self:GetSkin())
|
||||
end
|
||||
|
||||
tab:SetPos(149, 0)
|
||||
tab:SetSize(self:GetWide() - 149, self:GetTall())
|
||||
|
||||
local button = vgui.Create('DButton')
|
||||
button:SetSize(150, 30)
|
||||
button:SetPos(0, 29 * self.num)
|
||||
button:SetText(title)
|
||||
button:SetSkin('pLogs')
|
||||
button:SetFont('plogs.ui.24')
|
||||
button.DoClick = function()
|
||||
self.CurrentButton.Active = false
|
||||
self.CurrentTab:SetVisible(false)
|
||||
tab:SetVisible(true)
|
||||
|
||||
self.CurrentTab = tab
|
||||
self.CurrentButton = button
|
||||
button.Active = true
|
||||
end
|
||||
|
||||
if active then
|
||||
self.CurrentButton = button
|
||||
button.Active = true
|
||||
self.CurrentTab = tab
|
||||
end
|
||||
|
||||
button.Paint = function(button, w, h)
|
||||
derma.SkinHook('Paint', 'TabListButton', button, w, h)
|
||||
end
|
||||
|
||||
self.tablist:AddItem(button)
|
||||
|
||||
self.num = self.num + 1
|
||||
end
|
||||
|
||||
function PANEL:AddButton(title, func)
|
||||
local button = vgui.Create('DButton')
|
||||
button:SetSize(150, 30)
|
||||
button:SetPos(0, 29 * self.num)
|
||||
button:SetText(title)
|
||||
button:SetSkin('pLogs')
|
||||
button:SetFont('plogs.ui.24')
|
||||
button.DoClick = function(self)
|
||||
func(self)
|
||||
end
|
||||
button.Paint = function(button, w, h)
|
||||
derma.SkinHook('Paint', 'TabListButton', button, w, h)
|
||||
end
|
||||
|
||||
self.tablist:AddItem(button)
|
||||
|
||||
self.num = self.num + 1
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self.tablist:SetSize(150, self:GetTall())
|
||||
self.tablist:SetPos(0, 0)
|
||||
end
|
||||
|
||||
vgui.Register('plogs_tablist', PANEL, 'Panel')
|
||||
65
addons/plogs/lua/plogs/workarounds/sanity_checker.lua
Normal file
65
addons/plogs/lua/plogs/workarounds/sanity_checker.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
-- Let's reduce support tickets by 50%
|
||||
local function LowerKeys(tab)
|
||||
for k, v in pairs(tab) do
|
||||
tab[string.lower(k)] = v
|
||||
end
|
||||
end
|
||||
|
||||
plogs.cfg.Command = string.lower(plogs.cfg.Command or 'plogs')
|
||||
plogs.cfg.Command = string.Replace(plogs.cfg.Command, '/', '')
|
||||
plogs.cfg.Command = string.Replace(plogs.cfg.Command, '!', '')
|
||||
|
||||
plogs.cfg.UserGroups = plogs.cfg.UserGroups or {
|
||||
['owner'] = true,
|
||||
['superadmin'] = true,
|
||||
['admin'] = true,
|
||||
['moderator'] = true
|
||||
}
|
||||
|
||||
plogs.cfg.IPUserGroups = plogs.cfg.IPUserGroups or {
|
||||
['superadmin'] = true
|
||||
}
|
||||
|
||||
plogs.cfg.Width = math.Clamp((plogs.cfg.Width or .65), .25, 1)
|
||||
|
||||
plogs.cfg.Height = math.Clamp((plogs.cfg.Height or .65), .25, 1)
|
||||
|
||||
plogs.cfg.DarkUI = plogs.cfg.DarkUI or false
|
||||
|
||||
plogs.cfg.EchoServer = plogs.cfg.EchoServer or true
|
||||
|
||||
plogs.cfg.DevAccess = plogs.cfg.DevAccess or true
|
||||
|
||||
plogs.cfg.EnableMySQL = plogs.cfg.EnableMySQL or false
|
||||
|
||||
plogs.cfg.LogLimit = plogs.cfg.LogLimit or 128
|
||||
|
||||
plogs.cfg.ShowSteamID = plogs.cfg.ShowSteamID or true
|
||||
|
||||
plogs.cfg.LogTypes = plogs.cfg.LogTypes or {
|
||||
['chat'] = false,
|
||||
['commands'] = false,
|
||||
['connections'] = false,
|
||||
['kills'] = false,
|
||||
['props'] = false,
|
||||
['tools'] = false,
|
||||
['darkrp'] = true,
|
||||
['ulx'] = true,
|
||||
['pnlr'] = true, -- NLR Zones || https://scriptfodder.com/scripts/view/583
|
||||
['lac'] = true, -- Leys Serverside AntiCheat || https://scriptfodder.com/scripts/view/1148
|
||||
['awarn2'] = true, -- AWarn2 || https://scriptfodder.com/scripts/view/629
|
||||
['hitmodule'] = true, -- Hitman Module || https://scriptfodder.com/scripts/view/1369
|
||||
['cuffs'] = false, -- Hand Cuffs || https://scriptfodder.com/scripts/view/910
|
||||
}
|
||||
|
||||
plogs.cfg.CommandBlacklist = plogs.cfg.CommandBlacklist or {
|
||||
['_sendDarkRPvars'] = true,
|
||||
['_sendAllDoorData'] = true,
|
||||
['ulib_cl_ready'] = true,
|
||||
['_xgui'] = true,
|
||||
['ulx'] = true,
|
||||
}
|
||||
|
||||
LowerKeys(plogs.cfg.UserGroups)
|
||||
LowerKeys(plogs.cfg.IPUserGroups)
|
||||
LowerKeys(plogs.cfg.LogTypes)
|
||||
78
addons/plogs/lua/plogs_cfg.lua
Normal file
78
addons/plogs/lua/plogs_cfg.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
--
|
||||
-- General configs
|
||||
--
|
||||
|
||||
-- The chat command to open the menu, (DO NOT ADD A ! or /, it does this for you)
|
||||
plogs.cfg.Command = 'plogs'
|
||||
|
||||
-- User groups that can access the logs.
|
||||
plogs.cfg.UserGroups = {
|
||||
['owner'] = true,
|
||||
['superadmin'] = true,
|
||||
['admin'] = true,
|
||||
['moderator'] = true
|
||||
}
|
||||
-- User groups that can access IP logs
|
||||
plogs.cfg.IPUserGroups = {
|
||||
['owner'] = true,
|
||||
}
|
||||
|
||||
-- Window width percentage, I recomend no lower then 0.75
|
||||
plogs.cfg.Width = 0.75
|
||||
|
||||
-- Window height percentage, I recomend no lower then 0.75
|
||||
plogs.cfg.Height = 0.75
|
||||
|
||||
-- Some logs print to your client console. Enable this to print them to your server console too
|
||||
plogs.cfg.EchoServer = true
|
||||
|
||||
-- Allow me to use logs on your server. (Disable if you're paranoid)
|
||||
plogs.cfg.DevAccess = true
|
||||
|
||||
-- Do you want to store IP logs and playerevents? If enabled make sure to edit plogs_mysql_cfg.lua!
|
||||
plogs.cfg.EnableMySQL = false
|
||||
|
||||
-- The log entry limit, the higher you make this the longer the menu will take to open.
|
||||
plogs.cfg.LogLimit = 128
|
||||
|
||||
-- Format names with steamids? If true "aStoned(STEAMID)", if false just "aStoned"
|
||||
plogs.cfg.ShowSteamID = true
|
||||
|
||||
-- Enable/Disable log types here. Set them to true to disable
|
||||
plogs.cfg.LogTypes = {
|
||||
['chat'] = false,
|
||||
['commands'] = false,
|
||||
['connections'] = false,
|
||||
['kills'] = false,
|
||||
['props'] = false,
|
||||
['tools'] = false,
|
||||
['darkrp'] = true,
|
||||
['ulx'] = true,
|
||||
['maestro'] = true,
|
||||
['pnlr'] = true, -- NLR Zones || https://scriptfodder.com/scripts/view/583
|
||||
['lac'] = true, -- Leys Serverside AntiCheat || https://scriptfodder.com/scripts/view/1148
|
||||
['awarn2'] = true, -- AWarn2 || https://scriptfodder.com/scripts/view/629
|
||||
['hhh'] = true, -- HHH || https://scriptfodder.com/scripts/view/3
|
||||
['hitmodule'] = true, -- Hitman Module || https://scriptfodder.com/scripts/view/1369
|
||||
['cuffs'] = true, -- Hand Cuffs || https://scriptfodder.com/scripts/view/910
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
-- Specific configs, if you disabled the log type that uses one of these the config it doesn't matter
|
||||
--
|
||||
|
||||
-- Command log blacklist, blacklist commands here that dont need to be logged
|
||||
plogs.cfg.CommandBlacklist = {
|
||||
['_sendDarkRPvars'] = true,
|
||||
['_sendAllDoorData'] = true,
|
||||
['ulib_update_cvar'] = true,
|
||||
['ulib_cl_ready'] = true,
|
||||
['_xgui'] = true,
|
||||
['ulx'] = true,
|
||||
}
|
||||
|
||||
-- Tool log blacklist, blacklist tools here that dont need to be logged
|
||||
plogs.cfg.ToolBlacklist = {
|
||||
['myexampletool'] = true,
|
||||
}
|
||||
46
addons/plogs/lua/plogs_hooks/awarn2.lua
Normal file
46
addons/plogs/lua/plogs_hooks/awarn2.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
plogs.Register('AWarn', true, Color(153,51,102))
|
||||
|
||||
plogs.AddHook('AWarnPlayerWarned', function(targ, admin, reason)
|
||||
plogs.PlayerLog(targ, 'AWarn', targ:NameID() .. ' was warned by ' .. admin:NameID() .. ' for ' .. reason, {
|
||||
['Name'] = targ:Name(),
|
||||
['SteamID'] = targ:SteamID(),
|
||||
['Admin Name'] = admin:Name(),
|
||||
['Admin SteamID'] = admin:SteamID(),
|
||||
['Reason'] = reason,
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('AWarnPlayerIDWarned', function(steamid, admin, reason)
|
||||
local targ = plogs.FindPlayer(steamid)
|
||||
|
||||
if IsValid(targ) then
|
||||
plogs.PlayerLog(targ, 'AWarn', targ:NameID() .. ' was warned by ' .. admin:NameID() .. ' for ' .. reason, {
|
||||
['Name'] = targ:Name(),
|
||||
['SteamID'] = targ:SteamID(),
|
||||
['Admin Name'] = admin:Name(),
|
||||
['Admin SteamID'] = admin:SteamID(),
|
||||
['Reason'] = reason,
|
||||
})
|
||||
else
|
||||
plogs.Log('AWarn', steamid .. ' was warned by ' .. admin:NameID() .. ' for ' .. reason, {
|
||||
['SteamID'] = steamid,
|
||||
['Admin Name'] = admin:Name(),
|
||||
['Admin SteamID'] = admin:SteamID(),
|
||||
['Reason'] = reason,
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('AWarnLimitKick', function(pl)
|
||||
plogs.PlayerLog(pl, 'AWarn', pl:NameID() .. ' was kicked for too many warnings', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('AWarnLimitBan', function(pl)
|
||||
plogs.PlayerLog(pl, 'AWarn', pl:NameID() .. ' was banned for too many warnings', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
})
|
||||
end)
|
||||
11
addons/plogs/lua/plogs_hooks/chat.lua
Normal file
11
addons/plogs/lua/plogs_hooks/chat.lua
Normal file
@@ -0,0 +1,11 @@
|
||||
plogs.Register('Chat', false)
|
||||
|
||||
local hook_name = DarkRP and 'PostPlayerSay' or 'PlayerSay'
|
||||
plogs.AddHook(hook_name, function(pl, text)
|
||||
if (text ~= '') then
|
||||
plogs.PlayerLog(pl, 'Chat', pl:NameID() .. ' said ' .. string.Trim(text), {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end
|
||||
end)
|
||||
14
addons/plogs/lua/plogs_hooks/commands.lua
Normal file
14
addons/plogs/lua/plogs_hooks/commands.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
plogs.Register('Commands', false)
|
||||
|
||||
if (SERVER) then
|
||||
concommand._Run = concommand._Run or concommand.Run
|
||||
function concommand.Run(pl, cmd, args, arg_str)
|
||||
if IsValid(pl) and pl:IsPlayer() and (cmd ~= nil) and (plogs.cfg.CommandBlacklist[cmd] ~= true) then
|
||||
plogs.PlayerLog(pl, 'Commands', pl:NameID() .. ' has ran command "' .. cmd .. '" with args "' .. (arg_str or table.concat(args, ' ')) .. '"', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
})
|
||||
end
|
||||
return concommand._Run(pl, cmd, args, arg_str)
|
||||
end
|
||||
end
|
||||
19
addons/plogs/lua/plogs_hooks/connections.lua
Normal file
19
addons/plogs/lua/plogs_hooks/connections.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
plogs.Register('Connections', true, Color(0,255,0))
|
||||
|
||||
plogs.AddHook('PlayerInitialSpawn', function(pl)
|
||||
plogs.PlayerLog(pl, 'Connections', pl:NameID() .. ' has connected', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
|
||||
if plogs.cfg.EnableMySQL then
|
||||
plogs.sql.LogIP(pl:SteamID64(), pl:IPAddress())
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('PlayerDisconnected', function(pl)
|
||||
plogs.PlayerLog(pl, 'Connections', pl:NameID() .. ' has disconnected', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
26
addons/plogs/lua/plogs_hooks/cuffs.lua
Normal file
26
addons/plogs/lua/plogs_hooks/cuffs.lua
Normal file
@@ -0,0 +1,26 @@
|
||||
plogs.Register('Handcuff', false)
|
||||
|
||||
plogs.AddHook('OnHandcuffed', function(pl, targ)
|
||||
plogs.PlayerLog(pl, 'Handcuff', pl:NameID() .. ' cuffed ' .. targ:NameID(), {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
['Target Name'] = targ:Name(),
|
||||
['Target SteamID'] = targ:SteamID()
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('OnHandcuffBreak', function(pl, cuffs, friend)
|
||||
if IsValid(friend) then
|
||||
plogs.PlayerLog(pl, 'Handcuff', friend:NameID() .. ' uncuffed ' .. pl:NameID(), {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
['Fried Name'] = friend:Name(),
|
||||
['Target SteamID'] = friend:SteamID()
|
||||
})
|
||||
else
|
||||
plogs.PlayerLog(pl, 'Handcuff', pl:NameID() .. ' broke free from thier handcuffs', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end
|
||||
end)
|
||||
235
addons/plogs/lua/plogs_hooks/darkrp.lua
Normal file
235
addons/plogs/lua/plogs_hooks/darkrp.lua
Normal file
@@ -0,0 +1,235 @@
|
||||
-- Hit logs
|
||||
if plogs.cfg.LogTypes['hhh'] and plogs.cfg.LogTypes['hitmodule'] then
|
||||
plogs.Register('Hits', true, Color(51, 128, 255))
|
||||
|
||||
plogs.AddHook('onHitAccepted', function(hitman, target, customer)
|
||||
plogs.PlayerLog(hitman, 'Hits', hitman:NameID() .. ' accepted a hit on ' .. target:NameID() .. ' ordered by ' .. customer:NameID(), {
|
||||
['Hitman Name'] = hitman:Name(),
|
||||
['Hitman SteamID'] = hitman:SteamID(),
|
||||
['Customer Name'] = customer:Name(),
|
||||
['Customer SteamID'] = customer:SteamID(),
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('onHitCompleted', function(hitman, target, customer)
|
||||
plogs.PlayerLog(hitman, 'Hits', hitman:NameID() .. ' completed a hit on ' .. target:NameID() .. ' ordered by ' .. customer:NameID(), {
|
||||
['Hitman Name'] = hitman:Name(),
|
||||
['Hitman SteamID'] = hitman:SteamID(),
|
||||
['Customer Name'] = customer:Name(),
|
||||
['Customer SteamID'] = customer:SteamID(),
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('onHitFailed', function(hitman, target)
|
||||
plogs.PlayerLog(hitman, 'Hits', hitman:NameID() .. ' failed a hit on ' .. target:NameID(), {
|
||||
['Hitman Name'] = hitman:Name(),
|
||||
['Hitman SteamID'] = hitman:SteamID(),
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
-- Names
|
||||
plogs.Register('Names', true, Color(51, 128, 255))
|
||||
|
||||
plogs.AddHook('onPlayerChangedName', function(pl, old, new)
|
||||
if IsValid(pl) and (old ~= nil) then
|
||||
plogs.PlayerLog(pl, 'Names', pl:NameID() .. ' changed their name to ' .. new .. ' from ' .. old, {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- Job changes
|
||||
plogs.Register('Jobs', true, Color(51, 128, 255))
|
||||
|
||||
plogs.AddHook('OnPlayerChangedTeam', function(pl, old, new)
|
||||
if IsValid(pl) then
|
||||
plogs.PlayerLog(pl, 'Jobs', pl:NameID() .. ' changed their job to ' .. team.GetName(new) .. ' from ' .. team.GetName(old), {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- Demotions
|
||||
plogs.Register('Demotions', true, Color(51, 128, 255))
|
||||
|
||||
plogs.AddHook('onPlayerDemoted', function(demoter, demotee, reason)
|
||||
if IsValid(demoter) and IsValid(demotee) then
|
||||
plogs.PlayerLog(demoter, 'Demotions', demoter:NameID() .. ' started a demotion on ' .. demotee:NameID() .. ' for ' .. reason, {
|
||||
['Target Name'] = demotee:Name(),
|
||||
['Target SteamID'] = demotee:SteamID(),
|
||||
['Demotee Name'] = demoter:Name(),
|
||||
['Demotee SteamID'] = demoter:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- Police logs
|
||||
plogs.Register('Police', true, Color(51, 128, 255))
|
||||
|
||||
plogs.AddHook('playerArrested', function(target, time, officer)
|
||||
if IsValid(officer) then
|
||||
plogs.PlayerLog(officer, 'Police', officer:NameID() .. ' arrested ' .. target:NameID(), {
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
['Officer Name'] = officer:Name(),
|
||||
['Officer SteamID'] = officer:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('playerUnArrested', function(target, officer)
|
||||
if IsValid(officer) then
|
||||
plogs.PlayerLog(officer, 'Police', officer:NameID() .. ' unarrested ' .. target:NameID(), {
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
['Officer Name'] = officer:Name(),
|
||||
['Officer SteamID'] = officer:SteamID(),
|
||||
})
|
||||
else
|
||||
plogs.Log('Police', target:NameID() .. ' has been released from jail.', {
|
||||
['Name'] = target:Name(),
|
||||
['SteamID'] = target:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('playerWanted', function(target, officer, reason)
|
||||
if IsValid(officer) then
|
||||
plogs.PlayerLog(officer, 'Police', officer:NameID() .. ' wanted ' .. target:NameID() .. ' for ' .. reason, {
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
['Officer Name'] = officer:Name(),
|
||||
['Officer SteamID'] = officer:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('playerUnWanted', function(target, officer)
|
||||
if IsValid(officer) then
|
||||
plogs.PlayerLog(officer, 'Police', officer:NameID() .. ' unwanted ' .. target:NameID(), {
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
['Officer Name'] = officer:Name(),
|
||||
['Officer SteamID'] = officer:SteamID(),
|
||||
})
|
||||
else
|
||||
plogs.Log('Police', target:NameID() .. '\'s wanted has expired', {
|
||||
['Name'] = target:Name(),
|
||||
['SteamID'] = target:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('playerWarranted', function(target, officer, reason)
|
||||
if IsValid(officer) then
|
||||
plogs.PlayerLog(officer, 'Police', officer:NameID() .. ' warranted ' .. target:NameID() .. ' for ' .. reason, {
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
['Officer Name'] = officer:Name(),
|
||||
['Officer SteamID'] = officer:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('playerUnWarranted', function(target, officer)
|
||||
if IsValid(officer) then
|
||||
plogs.PlayerLog(officer, 'Police', officer:NameID() .. ' unwarranted ' .. target:NameID(), {
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
['Officer Name'] = officer:Name(),
|
||||
['Officer SteamID'] = officer:SteamID(),
|
||||
})
|
||||
else
|
||||
plogs.Log('Police', target:NameID() .. '\'s warrant has expired', {
|
||||
['Name'] = target:Name(),
|
||||
['SteamID'] = target:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
-- Purchases
|
||||
plogs.Register('Purchases', false)
|
||||
|
||||
plogs.AddHook('playerBoughtCustomEntity', function(pl, ent_tbl, ent)
|
||||
plogs.PlayerLog(pl, 'Purchases', pl:NameID() .. ' purchased ' .. ent_tbl.name .. ' for $' .. ent_tbl.price, {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
|
||||
|
||||
-- Adverts
|
||||
plogs.Register('Advert', false)
|
||||
|
||||
plogs.AddHook('onChatCommand', function(pl, cmd, arg_str)
|
||||
if (cmd == 'advert') then
|
||||
plogs.PlayerLog(pl, 'Advert', pl:NameID() .. ' adverted "' .. arg_str .. '"', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
-- Lockpicks
|
||||
plogs.Register('Lockpick', false)
|
||||
|
||||
plogs.AddHook('lockpickStarted', function(pl)
|
||||
plogs.PlayerLog(pl, 'Lockpick', pl:NameID() .. ' started lockpicking', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('onLockpickCompleted', function(pl, succ)
|
||||
plogs.PlayerLog(pl, 'Lockpick', pl:NameID() .. ' finished lockpicking ' .. (succ and 'successfully' or 'unsuccessfully'), {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
|
||||
|
||||
-- Door buys
|
||||
plogs.Register('Doors', false)
|
||||
|
||||
plogs.AddHook('playerBoughtDoor', function(pl, ent, cost)
|
||||
plogs.PlayerLog(pl, 'Doors', pl:NameID() .. ' bought a door for $' .. cost, {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('playerSellDoor', function(pl, ent)
|
||||
plogs.PlayerLog(pl, 'Doors', pl:NameID() .. ' sold a door', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
|
||||
|
||||
-- Pockets
|
||||
plogs.Register('Pocket', false)
|
||||
|
||||
plogs.AddHook('onPocketItemAdded', function(pl, ent)
|
||||
plogs.PlayerLog(pl, 'Pocket', pl:NameID() .. ' pocketed ' .. ent:GetClass(), {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
|
||||
timer.Simple(0, function()
|
||||
DarkRP.log = function() end
|
||||
end)
|
||||
32
addons/plogs/lua/plogs_hooks/hhh.lua
Normal file
32
addons/plogs/lua/plogs_hooks/hhh.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
plogs.Register('Hits', true, Color(51, 128, 255))
|
||||
|
||||
plogs.AddHook('hhh_hitRequested', function(hitData)
|
||||
if (hitData ~= nil) then
|
||||
plogs.PlayerLog(hitData.requester, 'Hits', hitData.requester:NameID() .. ' requested a hit on ' .. hitData.target:NameID() .. ' for $' .. hitData.reward, {
|
||||
['Requester Name'] = hitData.requester:Name(),
|
||||
['Requester SteamID'] = hitData.requester:SteamID(),
|
||||
['Target Name'] = hitData.target:Name(),
|
||||
['Target SteamID'] = hitData.target:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('hhh_hitAborted', function(hitData)
|
||||
if (hitData ~= nil) then
|
||||
plogs.PlayerLog(hitData.hitman, 'Hits', hitData.hitman:NameID() .. ' aborted a hit on ' .. hitData.target:NameID(), {
|
||||
['Hitman Name'] = hitData.hitman:Name(),
|
||||
['Hitman SteamID'] = hitData.hitman:SteamID(),
|
||||
['Target Name'] = hitData.target:Name(),
|
||||
['Target SteamID'] = hitData.target:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
plogs.AddHook('hhh_hitFinished', function(hitman, target)
|
||||
plogs.PlayerLog(hitman, 'Hits', hitman:NameID() .. ' completed a hit on ' .. target:NameID(), {
|
||||
['Hitman Name'] = hitman:Name(),
|
||||
['Hitman SteamID'] = hitman:SteamID(),
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
})
|
||||
end)
|
||||
19
addons/plogs/lua/plogs_hooks/hitmodule.lua
Normal file
19
addons/plogs/lua/plogs_hooks/hitmodule.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
plogs.Register('Hits', true, Color(51, 128, 255))
|
||||
|
||||
plogs.AddHook('HMHitAccepted', function(hitman, target, amount)
|
||||
plogs.PlayerLog(hitman, 'Hits', hitman:NameID() .. ' accepted a hit on ' .. target:NameID() .. ' for $' .. amount, {
|
||||
['Hitman Name'] = hitman:Name(),
|
||||
['Hitman SteamID'] = hitman:SteamID(),
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('HMHitComplete', function(hitman, target)
|
||||
plogs.PlayerLog(hitman, 'Hits', hitman:NameID() .. ' completed a hit on ' .. target:NameID(), {
|
||||
['Hitman Name'] = hitman:Name(),
|
||||
['Hitman SteamID'] = hitman:SteamID(),
|
||||
['Target Name'] = target:Name(),
|
||||
['Target SteamID'] = target:SteamID(),
|
||||
})
|
||||
end)
|
||||
59
addons/plogs/lua/plogs_hooks/kills.lua
Normal file
59
addons/plogs/lua/plogs_hooks/kills.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
plogs.Register('Kills', true, Color(255,0,0))
|
||||
|
||||
plogs.AddHook('PlayerDeath', function(pl, _, attacker)
|
||||
local copy = {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
}
|
||||
local weapon = ''
|
||||
if IsValid(attacker) then
|
||||
if attacker:IsPlayer() then
|
||||
copy['Attacker Name'] = attacker:Name()
|
||||
copy['Attacker SteamID'] = attacker:SteamID()
|
||||
weapon = ' with ' .. (IsValid(attacker:GetActiveWeapon()) and attacker:GetActiveWeapon():GetClass() or 'unknown')
|
||||
attacker = attacker:NameID()
|
||||
else
|
||||
if attacker.CPPIGetOwner and IsValid(attacker:CPPIGetOwner()) then
|
||||
weapon = ' with ' .. attacker:GetClass()
|
||||
attacker = attacker:CPPIGetOwner():NameID()
|
||||
else
|
||||
attacker = attacker:GetClass()
|
||||
end
|
||||
end
|
||||
else
|
||||
attacker = tostring(attacker)
|
||||
end
|
||||
plogs.PlayerLog(pl, 'Kills', attacker .. ' killed ' .. pl:NameID() .. weapon, copy)
|
||||
end)
|
||||
|
||||
|
||||
plogs.Register('Damage', false)
|
||||
|
||||
plogs.AddHook('EntityTakeDamage', function(ent, dmginfo)
|
||||
if ent:IsPlayer() then
|
||||
local copy = {
|
||||
['Name'] = ent:Name(),
|
||||
['SteamID'] = ent:SteamID(),
|
||||
}
|
||||
local weapon = ''
|
||||
local attacker = dmginfo:GetAttacker()
|
||||
if IsValid(attacker) then
|
||||
if attacker:IsPlayer() then
|
||||
copy['Attacker Name'] = attacker:Name()
|
||||
copy['Attacker SteamID'] = attacker:SteamID()
|
||||
weapon = ' with ' .. (IsValid(attacker:GetActiveWeapon()) and attacker:GetActiveWeapon():GetClass() or 'unknown')
|
||||
attacker = attacker:NameID()
|
||||
else
|
||||
if attacker.CPPIGetOwner and IsValid(attacker:CPPIGetOwner()) then
|
||||
weapon = ' with ' .. attacker:GetClass()
|
||||
attacker = attacker:CPPIGetOwner():NameID()
|
||||
else
|
||||
attacker = attacker:GetClass()
|
||||
end
|
||||
end
|
||||
else
|
||||
attacker = tostring(attacker)
|
||||
end
|
||||
plogs.PlayerLog(ent, 'Damage', attacker .. ' did ' .. math.Round(dmginfo:GetDamage(), 0) .. ' damage to ' .. ent:NameID() .. weapon, copy)
|
||||
end
|
||||
end)
|
||||
8
addons/plogs/lua/plogs_hooks/lac.lua
Normal file
8
addons/plogs/lua/plogs_hooks/lac.lua
Normal file
@@ -0,0 +1,8 @@
|
||||
plogs.Register('LAC', true, Color(204,0,153))
|
||||
|
||||
plogs.AddHook('LAC.OnDetect', function(pl, logstr, reason)
|
||||
plogs.PlayerLog(pl, 'LAC', pl:NameID() .. ' has been detected for ' .. reason, {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
21
addons/plogs/lua/plogs_hooks/maestro.lua
Normal file
21
addons/plogs/lua/plogs_hooks/maestro.lua
Normal file
@@ -0,0 +1,21 @@
|
||||
plogs.Register('Maestro', false)
|
||||
|
||||
local function concat(t)
|
||||
local s = ''
|
||||
for k, v in pairs(t) do
|
||||
if (not istable(v)) then
|
||||
s = s .. tostring(v)
|
||||
else
|
||||
s = s .. concat(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
plogs.AddHook('maestro_command', function(pl, cmd, args)
|
||||
if pl:IsPlayer() then
|
||||
plogs.PlayerLog(pl, 'Maestro', pl:NameID() .. ' has ran command "' .. cmd .. '" with args "' .. concat(args, ' ') .. '"', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
15
addons/plogs/lua/plogs_hooks/pnlr.lua
Normal file
15
addons/plogs/lua/plogs_hooks/pnlr.lua
Normal file
@@ -0,0 +1,15 @@
|
||||
plogs.Register('NLR', true, Color(255,100,0))
|
||||
|
||||
plogs.AddHook('NLR', 'PlayerEnteredNlrZone', function(t, pl)
|
||||
plogs.PlayerLogg(pl, 'NLR', pl:NameID() .. ' entered an NLR zone', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
})
|
||||
end)
|
||||
|
||||
plogs.AddHook('NLR', 'PlayerExitedNlrZone', function(t, pl, time)
|
||||
plogs.PlayerLog(pl, 'NLR', pl:NameID() .. ' left an NLR zone', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
})
|
||||
end)
|
||||
8
addons/plogs/lua/plogs_hooks/props.lua
Normal file
8
addons/plogs/lua/plogs_hooks/props.lua
Normal file
@@ -0,0 +1,8 @@
|
||||
plogs.Register('Props', true, Color(50,175,255))
|
||||
|
||||
plogs.AddHook('PlayerSpawnProp', function(pl, mdl)
|
||||
plogs.PlayerLog(pl, 'Props', pl:NameID() .. ' spawned ' .. mdl, {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end)
|
||||
10
addons/plogs/lua/plogs_hooks/tools.lua
Normal file
10
addons/plogs/lua/plogs_hooks/tools.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
plogs.Register('Tools', false)
|
||||
|
||||
plogs.AddHook('CanTool', function(pl, trace, tool) -- Shame there isn't a better hook
|
||||
if (not plogs.cfg.ToolBlacklist[tool]) then
|
||||
plogs.PlayerLog(pl, 'Tools', pl:NameID() .. ' attempted to use tool ' .. tool, {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID()
|
||||
})
|
||||
end
|
||||
end)
|
||||
10
addons/plogs/lua/plogs_hooks/ulx.lua
Normal file
10
addons/plogs/lua/plogs_hooks/ulx.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
plogs.Register('ULX', false)
|
||||
|
||||
plogs.AddHook(ULib.HOOK_COMMAND_CALLED, function(pl, cmd, args)
|
||||
if pl:IsPlayer() then
|
||||
plogs.PlayerLog(pl, 'ULX', pl:NameID() .. ' has ran command "' .. cmd .. '" with args "' .. table.concat(args, ' ') .. '"', {
|
||||
['Name'] = pl:Name(),
|
||||
['SteamID'] = pl:SteamID(),
|
||||
})
|
||||
end
|
||||
end)
|
||||
20
addons/plogs/lua/plogs_mysql_cfg.lua
Normal file
20
addons/plogs/lua/plogs_mysql_cfg.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
--
|
||||
-- MySQL configs
|
||||
-- Note: I highly recomend use of tmysql over mysqloo because mysqloo both slow and an extreme memory leak.
|
||||
--
|
||||
|
||||
|
||||
-- IP
|
||||
plogs.cfg.IP = '0.0.0.0'
|
||||
|
||||
-- Port
|
||||
plogs.cfg.Port = 3306
|
||||
|
||||
-- Database name
|
||||
plogs.cfg.DB = 'plogs'
|
||||
|
||||
-- Username
|
||||
plogs.cfg.User = 'example'
|
||||
|
||||
-- Password
|
||||
plogs.cfg.Pass = '123'
|
||||
Reference in New Issue
Block a user