aboutsummaryrefslogtreecommitdiff
path: root/gamemode/core/database/sv_setup.lua
blob: 0d0eb749b5e96faf7f0319836d712b68e50074de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
--Adds the MySQLite global
nrequire("sv_mysqlite.lua")
local config = nrequire("config/sv_sql.lua")
local data = nrequire("config/sv_newplayer.lua")
local fn = nrequire("fn.lua")
local col = nrequire("colortheme.lua")
local inv = nrequire("inventory/inventory.lua")
local track = nrequire("sv_invtracker.lua")
local sql = {}

--Setup the database if it's not already
local setup_db = [[
CREATE TABLE IF NOT EXISTS playerdata(SteamID bigint primary key, PlayerData json, MetaData json)]]

--Create a new player
local create_player_query = [[
INSERT INTO playerdata (`SteamID`,`PlayerData`,`MetaData`) VALUES(%.0f,%q,%q)]]

--Get a player's data from the database
local fetch_player_query = [[
SELECT PlayerData, MetaData FROM playerdata WHERE SteamID=%.0f
]]

local save_player_query = [[
UPDATE playerdata SET MetaData=%q PlayerData=%q WHERE SteamID=%.0f
]]

local s_fmt = function(fmt,...)
	local args = {...}
	fn.map(args,MySQLite.SQLStr)
	return string.format(fmt,unpack(args))
end

local function q_fai(err,query)
	MsgC(col.console.red,string.format("Error executing %q, error:%s",query,err))
end

local function serialize_player(ply)
	local sdata = {}
	local invs = {}
	for k,v in pairs(ply.data.inventories) do
		invs[k] = {v.Name,v:Serialize()}
	end
	sdata.inventories = invs
	sdata.skills = ply.data.skills
	sdata.quests = ply.data.quests
	sdata.prayers = ply.data.prayers
	return util.TableToJSON(sdata)
end

local function deserialize_player(ply,str)
	print("Deseriailizeing player",ply," with ", str)
	track.ClearInventories(ply)
	local tbl = util.JSONToTable(str)
	local invs = tbl.inventories
	print("Inventories was", invs)
	PrintTable(invs)
	for k,v in pairs(invs) do
		print("Giveing inventory",v[1],v[2])
		track.GiveInventoryWithData(ply,v[1],v[2])
	end
	ply.data.skills = tbl.skills or {}
	ply.data.quests = tbl.quests or {}
	ply.data.prayers = tbl.prayers or {}
	track.SendPlayerData(ply)
end

local function connect()
	print("Connecting to the database...")
	MySQLite.initialize(config)
end
hook.Add("DatabaseInitialized","setup_table",function()
	local setup_success = function(res,li)
		print("Set up connection to db")
	end
	print("Setup query:",setup_db)
	MySQLite.query(setup_db,setup_success,q_fai)
end)
connect()

--Retruns (PlayerData, MetaData) or nil
function sql.GetPlayerData(ply)
	local s64 = ply:SteamID64()
	local q_str = s_fmt(fetch_player_query,s64)
	local q_suc = function(res,li)
		print("Got player's data:",res,type(res))
		if res == nil then
			print("Was nil, createing player data")
			sql.CreatePlayerTable(ply)
		else
			PrintTable(res)
			assert(#res == 1,"Not unique!")
			print("Was unique!")
			local meta = res[1].MetaData
			local plyd = res[1].PlayerData
			local mtbl = util.JSONToTable(meta)
			print("About to check if we are on the right server")
			if mtbl.lastserver ~= game.GetIPAddress() then
				print("Connecting player to ", mtbl.lastserver, " was on ", game.GetIPAddress())
				ply:ConCommand("connect " .. mtbl.lastserver)
				return
			end
			print("We were on the right server")
			local _,_,x,y,z = mtbl.lastlocation:find("([%d%.]+) ([%d%.]+) ([%d%.]+)")
			local vec = {x,y,z}
			for k,v in pairs(vec) do vec[k] = tonumber(v) end
			print("setting player pos to")
			PrintTable(vec)
			ply:SetPos(Vector(unpack(vec)))
			deserialize_player(ply,plyd)
		end
	end
	print("doing query",q_str)
	MySQLite.query(q_str,q_suc,q_fai)
end

function sql.CreatePlayerTable(ply)
	print("Createing player table....")
	local s64 = ply:SteamID64()
	print("steamid was", s64)
	local plytbl = data.newdata()
	local plymet = data.newmeta()
	local plydata = util.TableToJSON(plytbl)
	local metdata = util.TableToJSON(plymet)
	local q_str = s_fmt(create_player_query,s64,plydata,metdata)
	local q_suc = function(res,li)
		print("Inserted new player",ply)
		sql.GetPlayerData(ply)
	end
	print("doing query", q_str)
	MySQLite.query(q_str,q_suc,q_fai)
end

function sql.SendPlayerToInstance(ply,ls,ll)
	local s64 = ply:SteamID64()
	local plydata = serialize_player(ply)
	local plymeta = util.TableToJSON({
		lastserver = ls,
		lastlocation = ll
	})
	local q_str = s_fmt(save_player_query,plymeta,plydata,s64)
	local q_suc = function(res,li)
		print("Successfully saved player data")
	end
	MySQLite.query(q_str,q_suc,q_fai)
end

concommand.Add("DoQuery",function(ply,cmd,args)
	if args[1] == "create" then
		sql.CreatePlayerTable(ply)
	elseif args[1] == "get" then
		sql.GetPlayerData(ply)
	elseif args[1] == "send" then
		sql.SendPlayerToInstance(ply,args[2],args[3])
	else
		error("Command not understood:" .. args[1] .. "!")
	end
end)

return sql