· 8 years ago · Jul 03, 2018, 04:34 AM
1--See https://github.com/SuperiorServers/NoMultirun/
2
3local Module = {}
4Module.Name = "NoMultirun"
5Module.m_intUpdateRate = 30 --Seconds
6Module.m_intTimeoutDelay = 10 --Extra time to consider a session valid for
7
8function Module:GamemodeInitSQLTables()
9 GAMEMODE.SQL:PooledQueryWrite( 1, [[CREATE TABLE IF NOT EXISTS `server_sessions` (
10`steamid` VARCHAR(255) NOT NULL,
11`time` INT NOT NULL,
12`server` TEXT NOT NULL,
13PRIMARY KEY (`steamid`)
14) ENGINE=InnoDB;]] )
15
16 self.ServerID = g_SHA256( GetConVarString("ip").. ":".. GetConVarString("hostport") )
17
18 GAMEMODE.SQL:PooledQueryWrite( 1, ([[DELETE FROM server_sessions WHERE server = '%s';]]):format(self.ServerID) )
19 timer.Create( "GM:Module:NoMultirun", self.m_intUpdateRate, 0, function()
20 GAMEMODE.SQL:PooledQueryWrite( 1, ([[UPDATE server_sessions SET time = UNIX_TIMESTAMP() WHERE server = '%s';)]]):format(
21 self.ServerID
22 ) )
23 end )
24end
25
26do
27 local query = "SELECT steamid, server FROM server_sessions WHERE steamid='%s' AND time >= (UNIX_TIMESTAMP() -%d) AND server != '%s';"
28 function Module:AuthPlayer( strSID64, funcCallback )
29 GAMEMODE.SQL:QueryReadOnly( query:format(
30 strSID64,
31 self.m_intUpdateRate +self.m_intTimeoutDelay,
32 self.ServerID
33 ), function( tblData, q )
34 if #tblData > 0 then
35 game.KickID( util.SteamIDFrom64(strSID64), "Active player session on another server detected." )
36 else
37 if funcCallback then funcCallback() end
38 end
39 end )
40 end
41end
42
43function Module:CheckPassword( strSID64 )
44 self:AuthPlayer( strSID64 )
45end
46
47function Module:PlayerAuthed( pPlayer )
48 self:AuthPlayer( pPlayer:SteamID64(), function()
49 if not IsValid( pPlayer ) then return end
50
51 GAMEMODE.SQL:PooledQueryWrite( 1, ([[REPLACE INTO server_sessions(steamid, time, server) VALUES('%s', UNIX_TIMESTAMP(), '%s');]]):format(
52 pPlayer:SteamID64(),
53 self.ServerID
54 ), function()
55 if not IsValid( pPlayer ) then return end
56
57 pPlayer.m_bValidGameSession = true
58 if pPlayer.m_bGamemodeDataLoaded then --We need to actually start loading them now
59 pPlayer.m_bGamemodeDataLoaded = false
60 GAMEMODE.Player:PlayerReadyForData( pPlayer )
61 end
62 end )
63 end )
64end
65
66function Module:player_disconnect( tblData )
67 local sid64 = util.SteamIDTo64( tblData.networkid )
68 GAMEMODE.SQL:PooledQueryWrite( 1, ([[DELETE FROM server_sessions WHERE steamid = '%s' AND server = '%s';]]):format(
69 sid64,
70 self.ServerID
71 ) )
72end
73
74function Module:PlayerInitialSpawn( pPlayer )
75 if game.SinglePlayer() then
76 pPlayer.m_bValidGameSession = true
77 if pPlayer.m_bGamemodeDataLoaded then --We need to actually start loading them now
78 pPlayer.m_bGamemodeDataLoaded = false
79 GAMEMODE.Player:PlayerReadyForData( pPlayer )
80 end
81 return
82 end
83end
84
85function Module:OnLoad()
86 self:RequireHook( "player_disconnect" )
87 self:RequireHook( "PlayerAuthed" )
88 self:RequireHook( "CheckPassword" )
89 self:RequireHook( "GamemodeInitSQLTables" )
90
91 if game.SinglePlayer() then
92 self:RequireHook( "PlayerInitialSpawn" )
93 end
94end
95
96if not DEV_SERVER then
97 GM.Module:Register( Module )
98end