· 8 years ago · Apr 23, 2018, 10:38 AM
1local entity = FindMetaTable( "Entity" )
2local meta = FindMetaTable( "Player" )
3local panel = CLIENT and FindMetaTable( "Panel" )
4local GetEngineTable = entity.GetTable
5local pltostring = FindMetaTable"Player".__tostring
6
7local R=debug.getregistry()
8 local lowest = math.huge
9 local setted = meta
10 local function SetPlyMeta(t) if R[lowest]~=setted then ErrorNoHalt("1WOO".. (R[lowest]==panel and "<A>" or '<B>') .."OT\n") end setted = t R[lowest]=t end
11 local function GetPlyMeta() if R[lowest]~=setted then ErrorNoHalt( "2WOO".. (R[lowest]==panel and "<A>" or '<B>') .."OT\n") end return R[lowest] end
12
13 local fufu={}
14 MsgN"Finding Player meta from registry:"
15 for k,v in next,R do
16 if v==meta then
17 print(" > ",k)
18 if tonumber(k) and lowest>tonumber(k) then
19 fufu[k]=true
20 end
21 end
22 end
23
24local idx=0
25local function NewPlyMeta()
26 idx=idx+1
27 local myid=idx
28 local data = {MetaName = "Player"}
29 local datameta = {__index=meta}
30 setmetatable(data,datameta)
31 local t={
32 __index = data,
33 __newindex = data,
34 __tostring = function(self) return "PlayerIDX"..myid..pltostring(self) end,
35 --__metatable = meta,
36 --__len = function() end,
37 MetaName = "Player",
38 }
39 return t
40end
41
42hook.Add("Initialize","a",function()
43
44 MsgN"Finding Player meta from registry with filter:"
45
46 for k,v in next,R do
47 if v==meta then
48 print(">",k,fufu[k])
49 end
50 end
51
52 lowest=-1
53 for k,v in next,R do
54 if v==meta then
55 if fufu[k] and tonumber(k) and lowest<tonumber(k) then
56 lowest = k
57 print("GOTCHA",k)
58 end
59 end
60 end
61
62 SetPlyMeta(NewPlyMeta())
63end)
64
65local created=setmetatable({},{__mode='k'})
66hook.Add("OnEntityCreated","a",function(pl)
67 if created[pl] then
68 ErrorNoHalt("WAT RECREATE ",pl)
69 return
70 end
71
72 local plMeta_ = GetPlyMeta()
73 local plMeta = getmetatable(pl)
74 if plMeta==FindMetaTable"Player" then
75 ErrorNoHalt("WTF "..pltostring(pl).."\n")
76 end
77 if plMeta==FindMetaTable"Entity" then
78 return
79 end
80 if plMeta_ ~= plMeta then return end
81
82 SetPlyMeta(NewPlyMeta())
83 created[pl]=true
84
85 local dat = plMeta.__newindex
86 local datmeta = getmetatable(dat)
87 local tbl = GetEngineTable(pl)
88
89 if tbl==dat then ErrorNoHalt"WTF REINIT!!?!?!?!?\n" return end
90
91 setmetatable(tbl,datmeta)
92 plMeta.__index = tbl
93 plMeta.__newindex = tbl
94
95 for k,v in next,dat do
96 tbl[k]=tbl[k] or v
97 end
98end)
99
100local meta2={} meta2=getmetatable(meta)
101 if not meta2 then meta2={} setmetatable(meta,meta2) end
102
103 meta2.__index = entity
104
105
106
107if ( !sql.TableExists( "playerpdata" ) ) then
108
109 sql.Query( "CREATE TABLE IF NOT EXISTS playerpdata ( infoid TEXT NOT NULL PRIMARY KEY, value TEXT );" )
110
111end
112
113-- These are totally in the wrong place.
114function player.GetByUniqueID( ID )
115
116 for _, pl in pairs( player.GetAll() ) do
117
118 if ( pl:UniqueID() == ID ) then
119 return pl
120 end
121
122 end
123
124 return false
125
126end
127
128function player.GetBySteamID( ID )
129
130 ID = string.upper( ID )
131
132 for _, pl in pairs( player.GetAll() ) do
133
134 if ( pl:SteamID() == ID ) then
135 return pl
136 end
137
138 end
139
140 return false
141
142end
143
144function player.GetBySteamID64( ID )
145
146 ID = tostring( ID )
147
148 for _, pl in pairs( player.GetAll() ) do
149
150 if ( pl:SteamID64() == ID ) then
151 return pl
152 end
153
154 end
155
156 return false
157
158end
159
160--[[---------------------------------------------------------
161 Name: DebugInfo
162 Desc: Prints debug information for the player
163 ( this is just an example )
164-----------------------------------------------------------]]
165function meta:DebugInfo()
166
167 Msg( "Name: " .. self:Name() .. "\n" )
168 Msg( "Pos: " .. tostring( self:GetPos() ) .. "\n" )
169
170end
171
172-- Helpful aliases
173meta.GetName = meta.Nick
174meta.Name = meta.Nick
175
176--[[---------------------------------------------------------
177 Name: ConCommand
178 Desc: Overrides the default ConCommand function
179-----------------------------------------------------------]]
180if ( CLIENT ) then
181
182 local SendConCommand = meta.ConCommand
183 local CommandList = nil
184
185 function meta:ConCommand( command, bSkipQueue )
186
187 if ( bSkipQueue ) then
188 SendConCommand( self, command )
189 else
190 CommandList = CommandList or {}
191 table.insert( CommandList, command )
192 end
193
194 end
195
196 local function SendQueuedConsoleCommands()
197
198 if ( !CommandList ) then return end
199
200 local BytesSent = 0
201
202 for k, v in pairs( CommandList ) do
203
204 SendConCommand( LocalPlayer(), v )
205 CommandList[ k ] = nil
206
207 -- Only send x bytes per tick
208 BytesSent = BytesSent + v:len()
209 if ( BytesSent > 128 ) then
210 break
211 end
212
213 end
214
215 -- Turn the table into a nil so we can return easy
216 if ( table.Count( CommandList ) == 0 ) then
217
218 CommandList = nil
219
220 end
221
222 end
223
224 hook.Add( "Tick", "SendQueuedConsoleCommands", SendQueuedConsoleCommands )
225
226end
227
228--[[---------------------------------------------------------
229 GetPData
230 Saves persist data for this player
231-----------------------------------------------------------]]
232function meta:GetPData( name, default )
233
234 name = Format( "%s[%s]", self:UniqueID(), name )
235 local val = sql.QueryValue( "SELECT value FROM playerpdata WHERE infoid = " .. SQLStr( name ) .. " LIMIT 1" )
236 if ( val == nil ) then return default end
237
238 return val
239
240end
241
242--[[---------------------------------------------------------
243 SetPData
244 Set persistant data
245-----------------------------------------------------------]]
246function meta:SetPData( name, value )
247
248 name = Format( "%s[%s]", self:UniqueID(), name )
249 sql.Query( "REPLACE INTO playerpdata ( infoid, value ) VALUES ( " .. SQLStr( name ) .. ", " .. SQLStr( value ) .. " )" )
250
251end
252
253--[[---------------------------------------------------------
254 RemovePData
255 Remove persistant data
256-----------------------------------------------------------]]
257function meta:RemovePData( name )
258
259 name = Format( "%s[%s]", self:UniqueID(), name )
260 sql.Query( "DELETE FROM playerpdata WHERE infoid = " .. SQLStr( name ) )
261
262end
263
264--
265-- If they have their preferred default weapon then switch to it
266--
267function meta:SwitchToDefaultWeapon()
268
269 local weapon = self:GetInfo( "cl_defaultweapon" )
270
271 if ( self:HasWeapon( weapon ) ) then
272 self:SelectWeapon( weapon )
273 end
274
275end
276
277--
278-- Can use flashlight?
279--
280function meta:AllowFlashlight( bAble ) self.m_bFlashlight = bAble end
281function meta:CanUseFlashlight() return self.m_bFlashlight == true end
282
283-- A function to set up player hands, so coders don't have to copy all the code everytime.
284-- Call this in PlayerSpawn hook
285function meta:SetupHands( ply )
286
287 local oldhands = self:GetHands()
288 if ( IsValid( oldhands ) ) then
289 oldhands:Remove()
290 end
291
292 local hands = ents.Create( "gmod_hands" )
293 if ( IsValid( hands ) ) then
294 hands:DoSetup( self, ply )
295 hands:Spawn()
296 end
297
298end
299
300--
301-- Those functions have been removed from the engine since AddFlag and RemoveFlag
302-- made them obsolete, but we'll keep a Lua version of them for backward compatibility
303--
304if ( SERVER ) then
305
306--[[---------------------------------------------------------
307 Freeze
308 Freezes or unfreezes the player
309-----------------------------------------------------------]]
310function meta:Freeze( b )
311
312 if ( b ) then
313 self:AddFlags( FL_FROZEN )
314 else
315 self:RemoveFlags( FL_FROZEN )
316 end
317
318end
319
320--[[---------------------------------------------------------
321 GodEnable
322 Enables godmode on the player
323-----------------------------------------------------------]]
324function meta:GodEnable()
325
326 self:AddFlags( FL_GODMODE )
327
328end
329
330--[[---------------------------------------------------------
331 GodDisable
332 Disables godmode on the player
333-----------------------------------------------------------]]
334function meta:GodDisable()
335
336 self:RemoveFlags( FL_GODMODE )
337
338end
339
340end
341
342--[[---------------------------------------------------------
343 IsFrozen
344 Returns true if the player is frozen
345-----------------------------------------------------------]]
346function meta:IsFrozen()
347
348 return self:IsFlagSet( FL_FROZEN )
349
350end
351
352--[[---------------------------------------------------------
353 HasGodMode
354 Returns true if the player is in godmode
355-----------------------------------------------------------]]
356function meta:HasGodMode()
357
358 return self:IsFlagSet( FL_GODMODE )
359
360end