/
messages.lua
285 lines (220 loc) · 6.97 KB
/
messages.lua
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
--[[
Title: Messages
Handles messaging like logging, debug, etc.
]]
--[[
Function: tsay
Prints a message in talk say as well as in the user's consoles.
Parameters:
ply - The player to print to, set to nil to send to everyone. (Ignores this param if called on client)
msg - The message to print.
wait - *(Optional, defaults to false)* Wait one frame before posting. (Useful to use from things like chat hooks)
wasValid - *(INTERNAL USE ONLY)* This is flagged on waiting if the player *was* valid.
Revisions:
v2.10 - Initial
]]
function ULib.tsay( ply, msg, wait, wasValid )
ULib.checkArg( 1, "ULib.tsay", {"nil","Player","Entity"}, ply )
ULib.checkArg( 2, "ULib.tsay", "string", msg )
ULib.checkArg( 3, "ULib.tsay", {"nil","boolean"}, wait )
if wait then ULib.namedQueueFunctionCall( "ULibChats", ULib.tsay, ply, msg, false, ply and ply:IsValid() ) return end -- Call next frame
if SERVER and ply and not ply:IsValid() then -- Server console
if wasValid then -- This means we had a valid player that left, so do nothing
return
end
Msg( msg .. "\n" )
return
end
if CLIENT then
LocalPlayer():ChatPrint( msg )
return
end
if ply then
ply:ChatPrint( msg )
else
local players = player.GetAll()
for _, player in ipairs( players ) do
player:ChatPrint( msg )
end
end
end
local serverConsole = {} -- Used in the function below to identify the server console (internal use)
local function tsayColorCallback( ply, ... )
if CLIENT then
chat.AddText( ... )
return
end
if ply and ply ~= serverConsole and not ply:IsValid() then return end -- Player must have left the server
local args = { ... }
if ply == serverConsole then
for i=2, #args, 2 do
Msg( args[ i ] )
end
Msg( "\n" );
return
end
local current_chunk = { size = 0 }
local chunks = { current_chunk }
local max_chunk_size = 240
while #args > 0 do
local arg = table.remove( args, 1 )
local typ = type( arg )
local arg_size = typ == "table" and 4 or #arg + 2 -- Include null in strings, bool in both
if typ == "string" and current_chunk.size + arg_size > max_chunk_size then -- Split a large string up into multiple messages
local substr = arg:sub( 1, math.max( 1, max_chunk_size - current_chunk.size - 2 ) )
if #substr > 0 then
table.insert( current_chunk, substr )
end
table.insert( args, 1, arg:sub( #substr + 1) )
current_chunk = { size = 0 }
table.insert( chunks, current_chunk )
else
if current_chunk.size + arg_size > max_chunk_size then
current_chunk = { size = 0 }
table.insert( chunks, current_chunk )
end
current_chunk.size = current_chunk.size + arg_size
table.insert( current_chunk, arg )
end
end
for chunk_num=1, #chunks do
local chunk = chunks[ chunk_num ]
umsg.Start( "tsayc", ply )
umsg.Bool( chunk_num == #chunks )
umsg.Char( #chunk )
for i=1, #chunk do
local arg = chunk[ i ]
if type( arg ) == "string" then
umsg.Bool( true )
umsg.String( arg )
else
umsg.Bool( false )
umsg.Char( arg.r - 128 )
umsg.Char( arg.g - 128 )
umsg.Char( arg.b - 128 )
end
end
umsg.End()
end
end
if CLIENT then
local accumulator = {}
local function tsayColorHook( um )
local last = um:ReadBool()
local argn = um:ReadChar()
for i=1, argn do
if um:ReadBool() then
table.insert( accumulator, um:ReadString() )
else
table.insert( accumulator, Color( um:ReadChar() + 128, um:ReadChar() + 128, um:ReadChar() + 128) )
end
end
if last then
chat.AddText( unpack( accumulator ) )
accumulator = {}
end
end
usermessage.Hook( "tsayc", tsayColorHook )
end
--[[
Function: tsayColor
Prints a tsay message in color!
Parameters:
ply - The player to print to, set to nil to send to everyone. (Ignores this param if called on client)
wait - *(Optional, defaults to false)* Wait one frame before posting. (Useful to use from things like chat hooks)
... - color arg and text arg ad infinitum, color needs to come before the text it's coloring.
Revisions:
v2.40 - Initial.
]]
function ULib.tsayColor( ply, wait, ... )
if SERVER and ply and not ply:IsValid() then ply = serverConsole end -- Mark as server
if wait then ULib.namedQueueFunctionCall( "ULibChats", tsayColorCallback, ply, ... ) return end -- Call next frame
tsayColorCallback( ply, ... )
end
--[[
Function: tsayError
Just like tsay, but prints the string in red
Parameters:
ply - The player to print to, set to nil to send to everyone. (Ignores this param if called on client)
msg - The message to print.
wait - *(Optional, defaults to false)* Wait one frame before posting. (Useful to use from things like chat hooks)
Revisions:
v2.40 - Initial.
]]
function ULib.tsayError( ply, msg, wait )
return ULib.tsayColor( ply, wait, Color( 255, 140, 39 ), msg )
end
--[[
Function: csay
Prints a message in center of the screen as well as in the user's consoles.
Parameters:
ply - The player to print to, set to nil to send to everyone. (Ignores this param if called on client)
msg - The message to print.
color - *(Optional, defaults to 255, 255, 255, 255)* The color of the text.
duration - *(Optional)* The amount of time to show the text.
fade - *(Optional, defaults to 0.5)* The length of fade time
Revisions:
v2.10 - Added fade parameter. Fixed it sending the message multiple times.
v2.40 - Changed to use clientRPC.
]]
function ULib.csay( ply, msg, color, duration, fade )
if CLIENT then
ULib.csayDraw( msg, color, duration, fade )
Msg( msg .. "\n" )
return
end
ULib.clientRPC( ply, "ULib.csayDraw", msg, color, duration, fade )
ULib.console( ply, msg )
end
--[[
Function: console
Prints a message in the user's consoles.
Parameters:
ply - The player to print to, set to nil to send to everyone. (Ignores this param if called on client)
msg - The message to print.
]]
function ULib.console( ply, msg )
if CLIENT or (ply and not ply:IsValid()) then
Msg( msg .. "\n" )
return
end
if ply then
ply:PrintMessage( HUD_PRINTCONSOLE, msg .. "\n" )
else
local players = player.GetAll()
for _, player in ipairs( players ) do
player:PrintMessage( HUD_PRINTCONSOLE, msg .. "\n" )
end
end
end
--[[
Function: error
Gives an error to console.
Parameters:
s - The string to use as the error message
]]
function ULib.error( s )
if CLIENT then
Msg( "[LC ULIB ERROR] " .. s .. "\n" )
else
Msg( "[LS ULIB ERROR] " .. s .. "\n" )
end
end
--[[
Function: debugFunctionCall
Prints a function call, very useful for debugging.
Parameters:
name - The name of the function called.
... - all arguments to the function.
Revisions:
v2.40 - Now uses print instead of Msg, since Msg seems to have a low max length.
Changed how the variable length params work so you can pass nil followed by more params
]]
function ULib.debugFunctionCall( name, ... )
local args = { ... }
print( "Function '" .. name .. "' called. Parameters:" )
for i=1, #args do
local value = ULib.serialize( args[ i ] )
print( "[PARAMETER " .. i .. "]: Type=" .. type( args[ i ] ) .. "\tValue=(" .. value .. ")" )
end
end