10 REGISTER_NET_TEMP(net_debug)
14 NET_HANDLE(net_debug, bool isNew)
16 Net_Accept(net_debug);
17 this.sv_entnum = ReadShort();
18 if (ReadByte()) make_pure(this);
19 this.origin_x = ReadCoord();
20 this.origin_y = ReadCoord();
21 this.origin_z = ReadCoord();
22 setorigin(this, this.origin);
23 this.debug = true; // identify server entities by this
24 this.classname = strzone(ReadString());
25 this.sourceLoc = strzone(ReadString());
31 bool debug_send(entity this, entity to, int sf)
33 int channel = MSG_ONE;
35 WriteHeader(channel, net_debug);
36 WriteShort(channel, etof(this));
37 WriteByte(channel, is_pure(this));
38 vector o = this.origin;
39 if (o == '0 0 0') // brushes
40 o = (this.absmin + this.absmax) / 2;
42 o += this.tag_entity.origin;
43 WriteCoord(channel, o.x); WriteCoord(channel, o.y); WriteCoord(channel, o.z);
44 WriteString(channel, this.classname);
45 WriteString(channel, this.sourceLoc);
56 * 3: on (.entnum != 0)
57 * 4: on (.origin == '0 0 0')
58 * 5: on (.debug != 0), server only
61 bool autocvar_debugdraw;
65 string autocvar_debugdraw_filter, autocvar_debugdraw_filterout;
67 vector project_3d_to_2d(vector vec);
70 if (!autocvar_debugdraw) return;
71 static int debugdraw_frame;
74 FOREACH_ENTITY(true, {
75 if (it.debugdraw_last == debugdraw_frame) continue;
77 FOREACH_ENTITY_RADIUS(it.origin, 100, it.debugdraw_last != debugdraw_frame, {
78 it.debugdraw_last = debugdraw_frame;
79 vector rgb = (it.debug) ? '0 0 1' : '1 0 0';
80 if (autocvar_debugdraw_filterout != "" && strhasword(autocvar_debugdraw_filterout, it.classname)) continue;
81 if (autocvar_debugdraw_filter != "" && !strhasword(autocvar_debugdraw_filter, it.classname)) continue;
82 if (autocvar_debugdraw == 3)
84 if (!it.entnum) continue;
86 if (autocvar_debugdraw == 4)
88 if (it.origin) continue;
90 if (autocvar_debugdraw == 5)
92 if (!it.debug) continue;
94 else if (autocvar_debugdraw > 5)
98 // if (it.modelindex) break;
99 // if (it.absmin) break;
100 // if (it.absmax) break;
101 // if (it.entnum) break;
102 // if (it.drawmask) break;
103 // if (it.predraw) break;
104 // if (it.move_movetype) break;
106 // if (it.origin) break;
107 // if (it.oldorigin) break;
108 // if (it.velocity) break;
109 // if (it.angles) break;
110 // if (it.avelocity) break;
111 // if (it.classname) break;
112 // if (it.model) break;
113 // if (it.frame) break;
114 // if (it.skin) break;
115 // if (it.effects) break;
116 // if (it.mins) break;
117 // if (it.maxs) break;
118 // if (it.size) break;
119 // if (it.touch) break;
120 // if (it.use) break;
121 // if (it.think) break;
122 // if (it.blocked) break;
123 // if (it.nextthink) break;
124 // if (it.chain) break;
125 // if (it.netname) break;
126 // if (it.enemy) break;
127 // if (it.flags) break;
128 // if (it.colormap) break;
129 // if (it.owner) break;
134 else if (is_pure(it))
136 if (autocvar_debugdraw < 2) continue;
139 vector o = it.origin;
141 o += it.tag_entity.origin;
142 vector pos = project_3d_to_2d(o);
143 if (pos.z < 0) continue;
146 drawcolorcodedstring2_builtin(pos,
147 sprintf("%d: '%s'@%s", (it.debug ? it.sv_entnum : etof(it)),
148 it.classname, it.sourceLoc),
149 sz * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL);
157 COMMON_COMMAND(debugdraw_sv, "Dump all server entities")
161 case CMD_REQUEST_COMMAND:
163 if (!autocvar_debugdraw) return;
166 for (entity e = NULL; (e = findfloat(e, debug, 0)) && rem > 0; )
168 if (autocvar_debugdraw < 2 && is_pure(e)) continue;
169 debug_send(e, caller, 0);
173 LOG_INFOF("%d server entities sent\n", n - rem);
178 case CMD_REQUEST_USAGE:
180 LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " debugdraw_sv"));
188 GENERIC_COMMAND(bufstr_get, "Examine a string buffer object")
192 case CMD_REQUEST_COMMAND:
194 int bufhandle = stof(argv(1));
195 int string_index = stof(argv(2));
196 string s = bufstr_get(bufhandle, string_index);
197 LOG_INFOF("%s\n", s);
202 case CMD_REQUEST_USAGE:
204 LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " bufstr_get bufhandle string_index"));
210 GENERIC_COMMAND(version, "Print the current version")
214 case CMD_REQUEST_COMMAND:
216 LOG_INFO(WATERMARK "\n");
220 case CMD_REQUEST_USAGE:
222 LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " version"));
229 void(float bufhandle, string pattern, string antipattern) buf_cvarlist = #517;
231 GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars")
235 case CMD_REQUEST_COMMAND:
238 int h = buf_create();
239 buf_cvarlist(h, "", "_"); // exclude all _ cvars as they are temporary
240 int n = buf_getsize(h);
241 for (int i = 0; i < n; ++i) {
242 string k = bufstr_get(h, i);
243 string v = cvar_string(k);
244 string d = cvar_defstring(k);
247 s = strcat(s, k, " \"", v, "\" // \"", d, "\"\n");
254 case CMD_REQUEST_USAGE:
256 LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " cvar_localchanges"));
262 #if ENABLE_DEBUGTRACE
263 REGISTER_STAT(TRACE_ENT, int)
265 bool autocvar_debugtrace;
267 REGISTER_MUTATOR(trace, autocvar_debugtrace);
269 .bool debug_trace_button;
271 MUTATOR_HOOKFUNCTION(trace, SV_StartFrame)
273 FOREACH_CLIENT(true, {
275 bool btn = PHYS_INPUT_BUTTON_HOOK(it);
276 if (btn == it.debug_trace_button) skip = true;
277 it.debug_trace_button = btn;
278 if (!btn || skip) continue;
279 FOREACH_ENTITY(true, {
280 it.solid_prev = it.solid;
281 it.solid = SOLID_BBOX;
283 vector forward = '0 0 0'; vector right = '0 0 0'; vector up = '0 0 0';
284 MAKEVECTORS(makevectors, it.v_angle, forward, right, up);
285 vector pos = it.origin + it.view_ofs;
286 traceline(pos, pos + forward * max_shot_distance, MOVE_NORMAL, it);
287 FOREACH_ENTITY(true, {
288 it.solid = it.solid_prev;
291 entity e = trace_ent;
293 STAT(TRACE_ENT, it) = i;
295 setorigin(e, e.origin + '0 0 100');
296 stuffcmd(it, sprintf("prvm_edict server %d\n", i));
302 void Trace_draw2d(entity this)
304 int e = STAT(TRACE_ENT);
306 vector pos = '0 0 0';
307 pos.y += vid_conheight / 2;
308 drawstring(pos, sprintf("prvm_edict server %d", e), '10 10 0', '1 1 1', 1, DRAWFLAG_NORMAL);
311 STATIC_INIT(TRACE_ENT)
313 entity e = TRACE_ENT = new_pure(TRACE_ENT);
314 e.draw2d = Trace_draw2d;
315 IL_PUSH(g_drawables_2d, e);
320 GENERIC_COMMAND(find, "Search through entities for matching classname")
324 case CMD_REQUEST_COMMAND:
327 FOREACH_ENTITY_CLASS_ORDERED(argv(1), true,
329 LOG_INFOF("%i (%s)\n", it, it.classname);
333 LOG_INFOF("Found %d entities\n", entcnt);
339 LOG_INFO("Incorrect parameters for ^2find^7\n");
341 case CMD_REQUEST_USAGE:
343 LOG_INFO("\nUsage:^3 " GetProgramCommandPrefix() " find classname\n");
344 LOG_INFO(" Where 'classname' is the classname to search for.\n");
350 GENERIC_COMMAND(findat, "Search through entities for matching origin")
354 case CMD_REQUEST_COMMAND:
356 vector match = stov(argv(1));
357 FOREACH_ENTITY_ORDERED(it.origin == match, LOG_INFOF("%i (%s)\n", it, it.classname));
362 LOG_INFO("Incorrect parameters for ^2findat^7\n");
363 case CMD_REQUEST_USAGE:
365 LOG_INFO("\nUsage:^3 " GetProgramCommandPrefix() " findat \"0 0 0\"\n");