14:24 <+bridge> [ddnet] is using `#pragma once` instead of headerguards a bad practice or wathsoever? 14:25 <+bridge> [ddnet] http://prntscr.com/ji4rb0 seems widely supported 14:26 <+bridge> [ddnet] `It is not standard and it is not portable. It injects the hosting machine's filesystem semantics into your program, in addition to locking you down to a vendor. ` hmm 14:50 <+bridge> [ddnet] @Ryozuki it's not standard 14:50 <+bridge> [ddnet] I wouldn't use it 14:50 <+bridge> [ddnet] aslong you dont write for embedded system just use it 14:54 <+bridge> [ddnet] why though? 14:54 <+bridge> [ddnet] because it saves some typing? 14:58 <+bridge> [ddnet] it looks better, it doesnt define anything, and depending on, if your IDE/whatever creates such things when creating the file header, yes it saves typing xd 14:59 <+bridge> [ddnet] and it's directly clear what you want.. pragma once = include once 15:01 <+bridge> [ddnet] yeah 15:01 <+bridge> [ddnet] vistual studio addes them 15:01 <+bridge> [ddnet] visual studio addes them 15:01 <+bridge> [ddnet] visual studio adds them 15:04 <+bridge> [ddnet] @Jupstar ✪ the other variant (preprocessor defines) also has some upsides. e.g. if you copy a header file, it still works. 15:04 <+bridge> [ddnet] isnt that more an argument for pragma once 15:04 <+bridge> [ddnet] you can just copy files 15:04 <+bridge> [ddnet] xD 15:04 <+bridge> [ddnet] essentially it boils down to "is #include the same a pasting the text there"? 15:05 <+bridge> [ddnet] e.g. there are some header libraries that get compiled by concatenating all of their headers 15:05 <+bridge> [ddnet] before #pragma once, just copying the header into your program is the same as #including it 15:05 <+bridge> [ddnet] not with #pragma once 15:05 <+bridge> [ddnet] well sure i sometimes use defines too, especially if i want it to be includuded by a specific file 15:05 <+bridge> [ddnet] 15:05 <+bridge> [ddnet] but often you just include 15:07 <+bridge> [ddnet] anyway. I don't think one should deviate from the standard just to save typing 15:07 <+bridge> [ddnet] i would say the standard just needs an update 15:08 <+bridge> [ddnet] then push for it 😛 15:08 <+bridge> [ddnet] but I don't think it'll go into the standard because it has some unclear semantics 15:09 <+bridge> [ddnet] e.g. what happens with symlinks, or hardlinks 15:09 <+bridge> [ddnet] suppose one file has `#include ` and the other has `#include ` 15:10 <+bridge> [ddnet] and `/usr/include/freetype` symlinks to `/usr/include` 15:10 <+bridge> [ddnet] does the file get included twice? or once? if it has `#pragma once` at the start 15:10 <+bridge> [ddnet] once 15:11 <+bridge> [ddnet] if the pos is the same 15:11 <+bridge> [ddnet] but what does that mean? "pos is the same"? 15:11 <+bridge> [ddnet] what happens if you hardlink header files? 15:12 <+bridge> [ddnet] well i actually more mean in an absolute path, and for hardlinks it would resolve the pos 15:12 <+bridge> [ddnet] the point is that "file identiy" is a not really defined property 15:12 <+bridge> [ddnet] hardlinks are just two names for the same file 15:13 <+bridge> [ddnet] there's two "absolute paths" for a hardlink 15:13 <+bridge> [ddnet] e.g. if I hardlink a to b, then afterwards, a and b are completely equivalent 15:13 <+bridge> [ddnet] I can delete b or I can delete a, and the other one will still be ok 15:13 <+bridge> [ddnet] indeed, then i would say the actual pos on hardware if you want xD 15:13 <+bridge> [ddnet] i mean gcc probably solved this havent they 15:14 <+bridge> [ddnet] we can look at their approximation 😄 15:14 <+bridge> [ddnet] good luck :D 15:14 <+bridge> [ddnet] but if you have two different freetype headers, it also doesnt garantuee you to what to use 15:15 <+bridge> [ddnet] i mean with defines 15:15 <+bridge> [ddnet] if they have the same content and were just copied into two places for installation, then the macro solution just works™ 15:15 <+bridge> [ddnet] but does that save you anyhting 15:15 <+bridge> [ddnet] if the content is the same anyway 15:16 <+bridge> [ddnet] yes. we won't get duplicate definition errors 15:16 <+bridge> [ddnet] (the reason we have header guards in the first place) 15:17 <+bridge> [ddnet] ah ok, you mean like completly same files ok 15:17 <+bridge> [ddnet] but then i'd say again gcc probably saved this issue 15:17 <+bridge> [ddnet] I doubt that they "solve" this 15:17 <+bridge> [ddnet] this would mean they detect equal contents of source files 15:18 <+bridge> [ddnet] yes 15:18 <+bridge> [ddnet] no 15:18 <+bridge> [ddnet] they just make it unique by some kind of name 15:20 <+bridge> [ddnet] Header files are stupid anyway, C++ modules ftw: https://clang.llvm.org/docs/Modules.html 15:21 <+bridge> [ddnet] 👍 15:24 <+bridge> [ddnet] anyway, since the STL or something does not garantuee to use the same define for your header, you might want to create a vector.h and define the same definition STL does on some system 15:24 <+bridge> [ddnet] so it's 1:1 15:25 <+bridge> [ddnet] xD 15:26 <+bridge> [ddnet] no, STL isn't allowed to define arbitrary macros 15:26 <+bridge> [ddnet] they have `__identifier` and `_Identifier` reserved for them 15:26 <+bridge> [ddnet] then some libs idc 15:26 <+bridge> [ddnet] this is the same problem as for symbols then 15:26 <+bridge> [ddnet] a library might define `function` and you also want to define `function` 15:27 <+bridge> [ddnet] the idea there is to prefix all your public stuff with your library name 15:27 <+bridge> [ddnet] meh. needs some enforced namespacing! 15:30 <+bridge> [ddnet] ok then other topic, what is your argument for a pointer not be handled as an own datatype in c++, if typdef is possible to be used on it 15:30 <+bridge> [ddnet] thats another thing i dont really like on c++ syntax 15:31 <+bridge> [ddnet] is this a "heinrich5991 must surely like every feature of c++"? 😮 15:32 <+bridge> [ddnet] no, but you seem to like it 15:32 <+bridge> [ddnet] maybe you have arguments i dont know 15:32 <+bridge> [ddnet] like int *a,b; 15:32 <+bridge> [ddnet] 15:32 <+bridge> [ddnet] since pointers arent an "own" datatype 15:32 <+bridge> [ddnet] (where did I seem like I like c++ particularly in that discussion?) 15:33 <+bridge> [ddnet] i am more refering to teeworlds code now 15:33 <+bridge> [ddnet] i know you like rust or smth 15:33 <+bridge> [ddnet] ^^ 15:34 <+bridge> [ddnet] mh. I'm not exactly exactly sure about that one 15:34 <+bridge> [ddnet] it would probably look weird with the other rules concerning variable declarations 15:35 <+bridge> [ddnet] e.g. int (*a), b; is equivalent 15:35 <+bridge> [ddnet] I think 15:35 <+bridge> [ddnet] yup, it is 15:35 <+bridge> [ddnet] i just dislike that this is possible: 15:35 <+bridge> [ddnet] typdef int* int_ptr; 15:35 <+bridge> [ddnet] 15:35 <+bridge> [ddnet] int_ptr a,b; 15:35 <+bridge> [ddnet] then it seems like you are allowed to make a ptr a datatype 15:36 <+bridge> [ddnet] yup, you are 15:36 <+bridge> [ddnet] it would look weird for arrays if it were to apply to both definitions 15:36 <+bridge> [ddnet] but you can mix arrays and pointers 15:36 <+bridge> [ddnet] `int a[10], b;` would be weird if `b` were an array in that declaration 15:38 <+bridge> [ddnet] but `int (*a)[10], b;` is the way to declare a pointer to an array, and `int (*a), b` is equivalent to `int *a, b` ­– it would be weird if it weren't 15:38 <+bridge> [ddnet] because then the only possible parantheses for `int *a, b;` would change something. hmm. 15:39 <+bridge> [ddnet] maybe one could formulate it in a way that ´(int *)a, b;` were possible (but that looks like a typecast) 15:39 <+bridge> [ddnet] maybe one could formulate it in a way that `(int *)a, b;` were possible (but that looks like a typecast) 15:39 <+bridge> [ddnet] maybe one could formulate it in a way that `(int *)a, b;` was possible (but that looks like a typecast) 15:40 <+bridge> [ddnet] you are right arrays are some kind of a problem, since they are actually just a pointer, except that the compiler can use it as an array too. 15:40 <+bridge> [ddnet] 15:40 <+bridge> [ddnet] But stilll then i would just forbid array declaration like that, or make it int[] a[10]. 15:40 <+bridge> [ddnet] no, arrays are not just a pointer, they have very different semantics 15:41 <+bridge> [ddnet] yes, but only for the compiler 15:41 <+bridge> [ddnet] `struct A { int a[10]; };` is 10 `int`s big, `struct B { int *b; };` is one pointer wide 15:41 <+bridge> [ddnet] sizeof and stuff like that 15:42 <+bridge> [ddnet] no, it's only in the compiler that they're treated somewhat the same, because arrays can decay (be implicitly converted) to pointers to the first element 15:43 <+bridge> [ddnet] yeah but what is that in asm? a new operand? the compiler just creates 10 *sizeof(int) bytes rest is up to the user 15:44 <+bridge> [ddnet] even if the compiler warns you if you "buffer overflow" it you can do it if you want 15:45 <+bridge> [ddnet] in asm, you basically have 10 variables of type width `sizeof(int)` 15:46 <+bridge> [ddnet] if you declare a pointer, you have one variable of pointer width, that may point to some memory location containing some `int`s 15:46 <+bridge> [ddnet] that's why i said, then it has to be operand int[]. But should be unique as a datatype 15:47 <+bridge> [ddnet] mh? 15:47 <+bridge> [ddnet] I don't understand your last sentence 15:48 <+bridge> [ddnet] int a[10], b; 15:48 <+bridge> [ddnet] shouldn't be allowed for the same reason pointers can be declared as datatypes 15:48 <+bridge> [ddnet] ah 15:48 <+bridge> [ddnet] that'd be possible 15:49 <+bridge> [ddnet] would forbid declaring multiple arrays at once though 15:49 <+bridge> [ddnet] why tho? int[] a[10], b[20] 15:49 <+bridge> [ddnet] (couldn't do `char aBuf[128], aBuf2[256];`) 15:49 <+bridge> [ddnet] oh 15:49 <+bridge> [ddnet] you want a different syntax there 15:50 <+bridge> [ddnet] yes, because i don't see a reason this isn't a new datatype 15:50 <+bridge> [ddnet] how would you distinguish `int (*a)[10]` and `int *(a[10])` in your new syntax? 15:50 <+bridge> [ddnet] an array of pointers? 15:51 <+bridge> [ddnet] a pointer to an array vs an array of pointers 15:51 <+bridge> [ddnet] int*[] array of pointer_int, int[]* ptr of an array_int 15:51 <+bridge> [ddnet] there were stars <.< 15:52 <+bridge> [ddnet] `int*[] array of pointer_int, int[]* ptr of an array_int`` 15:52 <+bridge> [ddnet] `int*[] array of pointer_int, int[]* ptr of an array_int` 15:53 <+bridge> [ddnet] pretty much reading from left to right 15:53 <+bridge> [ddnet] int_ptr_array 15:53 <+bridge> [ddnet] yea, I think there are languages that do it this way, although they reverse the entire declaration you give 15:54 <+bridge> [ddnet] mhh, probably 15:54 <+bridge> [ddnet] e.g. `x: *const u8` in rust 😛 15:54 <+bridge> [ddnet] for a constant (raw) pointer to a byte 15:55 <+bridge> [ddnet] yeah rust is pretty nice, only thing i dislike is this unsafe thing. I just can't imagine, if you are really able to write low level code without this 15:56 <+bridge> [ddnet] I think rust's argument is: you can keep your unsafes isolated in a module 15:56 <+bridge> [ddnet] that it's possible to code in rust can be seen by the fact that firefox includes rust code 15:56 <+bridge> [ddnet] yeah, but on mobile i get many crashes still xD 15:57 <+bridge> [ddnet] but since the rust version is out i use firefox alot more, it just runs better than before 15:57 <+bridge> [ddnet] if ppl would learn rust instead of java, the world would be a better place, rip 15:58 <+bridge> [ddnet] AFAIK the mobile version doesn't use rust yet 16:00 <+bridge> [ddnet] ok, strange that exactly with that update the crashes came 16:48 <+bridge> [ddnet] Well in embedded scenarios C will always shine so why bother with a new language, lets just teach everyone how to code competently in C \o/ 16:55 <+bridge> [ddnet] well in embedded scenarios ASM will always shine so why bother with a new language, let's just teach everyone how to code competently in C \o/ 16:55 <+bridge> [ddnet] well in embedded scenarios ASM will always shine so why bother with a new language, let's just teach everyone how to code competently in ASM \o/ 17:15 <+bridge> [ddnet] `typdef int* int_ptr;` 17:15 <+bridge> [ddnet] windows api does things like this 17:16 <+bridge> [ddnet] http://prntscr.com/ji7gjn 17:17 <+bridge> [ddnet] ASM shines in nothing silly man, it's just for exotic platforms where there is no libc (albeit there arent many left because C is amazing) 17:18 <+bridge> [ddnet] you and your C fanatism xD 17:18 <+bridge> [ddnet] No libc as in no C implementation before you argue semantics 🙂 17:19 <+bridge> [ddnet] @Ryozuki drink the koolaid join me and Ill show u the way 17:19 <+bridge> [ddnet] show me da way 17:20 <+bridge> [ddnet] @Learath2 what you think about dlang 17:21 <+bridge> [ddnet] Is more in the right direction imho but I havent had much chance to experiment with it in an actual project 20:07 <+bridge> [ddnet] rust! 20:21 <+bridge> [ddnet] rust! 20:30 <+bridge> [ddnet] C#😳 20:31 <+bridge> [ddnet] arnold-c! 20:41 <+bridge> [ddnet] pascal 20:51 <+bridge> [ddnet] Fuchsia C++! https://github.com/fuchsia-mirror/zircon/blob/master/docs/cxx.md 21:15 <+bridge> [ddnet] small question: 21:15 <+bridge> [ddnet] why do i only get max 24 players when i send the SERVERBROWSE_GETINFO_64_LEGACY packet? 21:15 <+bridge> [ddnet] validation of the response: 21:15 <+bridge> [ddnet] ```if ($data === false || $datalen < 15 || substr($data, 0, 15) !== "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffdtsf5") { 21:15 <+bridge> [ddnet] continue 2; 21:15 <+bridge> [ddnet] }``` 21:16 <+bridge> [ddnet] parsing of the players 21:16 <+bridge> [ddnet] ```$data = explode("\x00", $data); 21:16 <+bridge> [ddnet] for ($i = 11; isset($data[$i + 4]); $i += 5) { 21:16 <+bridge> [ddnet] $player = []; 21:16 <+bridge> [ddnet] $player['name'] = (string)$data[$i]; 21:16 <+bridge> [ddnet] $player['clan'] = (string)$data[$i + 1]; 21:16 <+bridge> [ddnet] $player['country'] = (int)$data[$i + 2]; 21:16 <+bridge> [ddnet] // $player['countrydata'] = self::getCountry($player['country']); 21:16 <+bridge> [ddnet] $player['score'] = (int)$data[$i + 3]; 21:16 <+bridge> [ddnet] $player['ingame'] = (bool)$data[$i + 4]; 21:16 <+bridge> [ddnet] $connection[1]['players'][] = $player; 21:16 <+bridge> [ddnet] }``` 21:16 <+bridge> [ddnet] https://i.imgur.com/RghbiUx.png 21:16 <+bridge> [ddnet] ```����������dtsf5``` 21:18 <+bridge> [ddnet] since it cancels me the copypaste with the \x00 a screenshot of the data 21:18 <+bridge> [ddnet] https://i.imgur.com/Nb1aXIs.png 21:18 <+bridge> [ddnet] parsing works but I only get max 24 players instead of the currently 29 online players 21:19 <+bridge> [ddnet] parsing works but I only get max 24 players instead of the currently 25(was the same when there were 31 online) online players 21:21 <+bridge> [ddnet] ``` $data = explode("\x00", $data); 21:21 <+bridge> [ddnet] for ($i = 11; isset($data[$i + 4]); $i += 5) { 21:21 <+bridge> [ddnet] $player['name'] = (string)$data[$i]; 21:21 <+bridge> [ddnet] $player['clan'] = (string)$data[$i + 1]; 21:21 <+bridge> [ddnet] $player['country'] = (int)$data[$i + 2]; 21:21 <+bridge> [ddnet] $player['score'] = (int)$data[$i + 3]; 21:21 <+bridge> [ddnet] $player['ingame'] = (bool)$data[$i + 4]; 21:21 <+bridge> [ddnet] $connection[1]['players'][] = $player; 21:21 <+bridge> [ddnet] }``` 21:22 <+bridge> [ddnet] why don't you use `SERVERBROWSE_GETINFO_64`? 😛 21:23 <+bridge> [ddnet] ah 21:23 <+bridge> [ddnet] and `SERVERBROWSE_GETINFO_64_LEGACY` only sends 24 players per packet 21:23 <+bridge> [ddnet] you should receive two of them 21:25 <+bridge> [ddnet] reason why legacy: 21:25 <+bridge> [ddnet] https://i.imgur.com/y3XUj8j.png 21:25 <+bridge> [ddnet] there is not one without legacy 21:26 <+bridge> [ddnet] there isn't one without legacy 21:30 <+bridge> [ddnet] send `SERVERBROWSE_GETINFO` with some special bytes in the front, let me check the source 21:33 <+bridge> [ddnet] @DaRealFreak `"xe\0\0\0\0\xff\xff\xff\xffinf3"` 21:36 <+bridge> [ddnet] thanks a lot, the 2nd packet worked too 21:36 <+bridge> [ddnet] https://i.imgur.com/jJ5iHU0.png 21:36 <+bridge> [ddnet] will update it to the default packet with the special bytes nonetheless though xD 21:36 <+bridge> [ddnet] thanks a lot 21:39 <+bridge> [ddnet] @DaRealFreak the good thing about the new packet is that you can send it to all servers. new servers supporting it respond with the new info packet, servers not supporting it respond with the old response 21:40 <+bridge> [ddnet] there are still 2 packets instead of only 1 like from the server not supporting it though or? 21:40 <+bridge> [ddnet] but i don't need a 2nd validation of the data so that's nice xD 21:41 <+bridge> [ddnet] you send this packet I gave you 21:41 <+bridge> [ddnet] if a server supports the new protocol, it will respond with all players in an appropriate number of packets 21:41 <+bridge> [ddnet] ah ok 21:41 <+bridge> [ddnet] if a server doesn't support the new protocol (and likely does not support 64 players), then it will respond with the vanilla response 21:42 <+bridge> [ddnet] yep already figured that out, thanks again^^ 21:43 <+bridge> [ddnet] but should be xe\0\0\0\0\xff\xff\xff\xffgie3 instead of the xe\0\0\0\0\xff\xff\xff\xffinf3 or? 21:43 <+bridge> [ddnet] but should be ```xe\0\0\0\0\xff\xff\xff\xffgie3``` instead of the ```xe\0\0\0\0\xff\xff\xff\xffinf3``` or? 21:46 <+bridge> [ddnet] @DaRealFreak https://github.com/timakro/teeworlds-server-info 21:46 <+bridge> [ddnet] timakro done this 21:49 <+bridge> [ddnet] @DaRealFreak yes 21:50 <+bridge> [ddnet] @Ryozuki directly ignores the spec 😦 `$data = "xe" . $server['_extratoken'] . "xD" . "\xff\xff\xff\xffgie3" . $server['_token'];` 21:50 <+bridge> [ddnet] the `"xD"` is supposed to be `"\0\0"` 21:50 <+bridge> [ddnet] it works 21:50 <+bridge> [ddnet] yes. but it's not forward-compatible 21:51 <+bridge> [ddnet] fordward compatible with what 21:51 <+bridge> [ddnet] with whatever we need next 21:51 <+bridge> [ddnet] 🤦 21:51 <+bridge> [ddnet] we specifically said these bytes are ought to be zeroed 21:51 <+bridge> [ddnet] we specifically said these bytes ought to be zeroed 21:51 <+bridge> [ddnet] "we" 21:51 <+bridge> [ddnet] where 21:51 <+bridge> [ddnet] in the initial PR 21:51 <+bridge> [ddnet] what pr 21:51 <+bridge> [ddnet] that added this info type 21:52 <+bridge> [ddnet] (the code in ddnet also does that) 21:52 <+bridge> [ddnet] well idc 21:52 <+bridge> [ddnet] contact timakro or smth 21:52 <+bridge> [ddnet] or make a pr 21:52 <+bridge> [ddnet] well, or don't recommend that library until someone fixes it 21:52 <+bridge> [ddnet] i will recommend it 21:52 <+bridge> [ddnet] these kind of things make software not work 21:52 <+bridge> [ddnet] like i did right now 21:52 <+bridge> [ddnet] these kinds of things are the reason why TLS 1.3 has low adoption 21:53 <+bridge> [ddnet] because someone thought it would be a good idea to only accept TLS <= 1.2 21:53 <+bridge> [ddnet] because that was "all that was out at the time" 21:53 <+bridge> [ddnet] i dont want to sound rude but i dont care 21:53 <+bridge> [ddnet] cool. I care about robust software 21:53 <+bridge> [ddnet] php 💩 21:54 <+bridge> [ddnet] https://github.com/ddnet/ddnet/pull/322 21:54 <+bridge> [ddnet] yeah documentation in a old pr 21:54 <+bridge> [ddnet] and a external repo 21:54 <+bridge> [ddnet] this is good work 21:54 <+bridge> [ddnet] or the reference implementation 21:54 <+bridge> [ddnet] which also does this 21:55 <+bridge> [ddnet] a good way to contributing in reliably software 21:55 <+bridge> [ddnet] not having docs 21:55 <+bridge> [ddnet] well, I wrote some docs and if someone wanted to find them, they would 21:55 <+bridge> [ddnet] what I don't really understand either why he is inserting 2 random bytes into the packet though aka his extratoken 21:55 <+bridge> [ddnet] you can do that to get a longer token from the ddnet server 21:55 <+bridge> [ddnet] you should probably do that 21:55 <+bridge> [ddnet] but good to see the structure of the packets, never checked the ddnet code before so got kinda lost in it a bit 21:56 <+bridge> [ddnet] `xe\0\0\xff\xff\xff\xffinf3` 21:56 <+bridge> [ddnet] @DaRealFreak ^ 21:56 <+bridge> [ddnet] ah ok will do that then 21:56 <+bridge> [ddnet] eh. 21:56 <+bridge> [ddnet] gie3 21:57 <+bridge> [ddnet] evil idea: we could probably get you to care, by dropping info requests with `"xD"` in the bytes that should be zeroed 21:58 <+bridge> [ddnet] go ahead 21:58 <+bridge> [ddnet] 😦 21:58 <+bridge> [ddnet] ❓ 21:59 <+bridge> [ddnet] you should drop all packets with extra bytes 21:59 <+bridge> [ddnet] reliably software 22:00 <+bridge> [ddnet] GLSL! 22:00 <+bridge> [ddnet] MATH 22:01 <+bridge> [ddnet] css3 22:17 <+Learath2> Ryozuki, you are why we have bad software :*( 22:18 <+Learath2> @DaRealFreak it takes decades to dig through the mess that is the ddnet/teeworlds source, we spend hours meditating on it just to find where things go 22:19 <+Learath2> heinrich5991: I'd be okay with merging a patch that drops invalid packets 22:19 <+bridge> [ddnet] Learath2: the problem would be that this would defeat the purpose of the forward-compatibility field 22:20 <+bridge> [ddnet] 😦 22:23 <+Learath2> i meant just xD :) 22:30 <+bridge> [ddnet] ah also a general question: had the cron task to update all player/server data on 5 minutes before, but like 50% of the servers refused to send me information back, anyone knows the exact number since 10 minutes is kinda meh sometimes 22:31 <+bridge> [ddnet] ah also a general question: had the cron task to update all player/server data on 5 minutes before, but like 50% of the servers refused to send me information back, anyone knows the exact number since 10 minutes is kinda meh sometimes(all servers I've gotten from the master server are sending me the information in 10 minute intervals, 50% refuse it in 5 minute intervals) 22:40 <+bridge> [ddnet] might just be packet loss 22:41 <+bridge> [ddnet] Learath2 oh im rly sry then :) 22:41 <+Learath2> no you arer not, you said you don't care :( software terrorist 22:42 <+bridge> [ddnet] :feelsgoodman: 22:43 <+bridge> [ddnet] 🔫