00:00 < bridge> <-StormAx> @blaiszephyr thanks for hoping on me 00:00 < bridge> <-StormAx> i finally made this 00:00 < bridge> <-StormAx> after 2 days of brain killing 00:00 < bridge> <-StormAx> https://cdn.discordapp.com/attachments/293493549758939136/1194777889430835421/Base_Profile_2024.01.10_-_20.49.05.02.DVR.mp4?ex=65b1969e&is=659f219e&hm=b850783d9e1c78fcace5dd0728e26f4c222ae6abf254634209cb2d9a35d0f6f8& 00:01 < bridge> *Pat Pat Pat* it'll be okay 00:01 < bridge> @stormaxd what are you doing? 00:02 < bridge> <-StormAx> old freeze 00:02 < bridge> <-StormAx> when ninja has a katana 00:02 < bridge> stars? 00:02 < bridge> ah 00:02 < bridge> no the katana 00:02 < bridge> i see 00:03 < bridge> I miss the stars. They were so perfect to time things + whenever I see old teeworlds videos or the trailer on steam it just feels like nostalgia and a whole different game :( 00:04 < bridge> @learath2 when ur promised clientside alternative to get them back 00:04 < bridge> i dont lol 00:05 < bridge> <-StormAx> its awful, add old starts is possible only by changing client version to 16010 00:05 < bridge> nah, you can simply render them clientside 00:06 < bridge> the client knows about all the info needed in order to replay the old server behaviour for the stars 00:06 < bridge> <-StormAx> hmmm 00:06 < bridge> <-StormAx> if you know that, where is stars is sending? 00:07 < bridge> wdym? 00:07 < bridge> <-StormAx> some netmsg, so server understand what to set freezebar || stars 00:07 < bridge> https://github.com/ddnet/ddnet/blob/42319546a6d3d98e300405cb11011fcee1332cce/src/game/server/entities/character.cpp#L2024 00:07 < bridge> <-StormAx> thanks 00:08 < bridge> np 00:08 < bridge> I'm just too lazy and busy to do it myself but I really want this as an option back 00:08 < bridge> clientsided 00:09 < bridge> good night 00:10 < bridge> As you can see in the link, the client with new HUD Version will not receive the stars. Simply render them clientside. 00:10 < bridge> The Info you need is sent via DDNetCharacter snap object. 00:11 < bridge> This info is also used by the client to render the freeze bar. 00:11 < bridge> <-StormAx> Ah 00:11 < bridge> <-StormAx> So i can just sat it as local variable 00:11 < bridge> <-StormAx> Cool 00:12 < bridge> <-StormAx> So i can just set it as local variable 00:12 < bridge> You mean as config option clientside? 00:12 < bridge> yes 00:12 < bridge> or what? 00:22 < bridge> <-StormAx> exacly what i ment 01:13 < bridge> <-StormAx> huh, i cant see any info i neer 01:14 < bridge> <-StormAx> or i just blind 02:27 < bridge> `GameServer()->ClientsMaskExcludeClientVersionAndHigher(VERSION_DDNET_NEW_HUD)` excludes clients that have the new hud (16010 or higher) 02:49 < bridge> important message from jupstar's weeb alter-ego 02:49 < bridge> https://images-ext-2.discordapp.net/external/nDvnb5lWaeiwa2KRFBniVsO-rscQ9-icUNC75LYyDlk/https/mosaic.fxtwitter.com/jpeg/1745151803346550836/GDgGUOSbMAA--T5/GDgGUOSbMAE3e_2/GDgGUORbMAE3c3F?format=webp&width=1440&height=748 05:38 < bridge> i though you're going to use sql or something 05:40 < bridge> I'm want to use sql for managing my server accounts, can someone give me a direction 05:40 < bridge> I want to use sql for managing my server accounts, can someone give me a direction 05:41 < bridge> managing accounts with c++ is pain and hard to scale 06:29 < bridge> SQL is very simple in nature and the glue to use it in cpp is really trivial 06:30 < bridge> also already implemented 06:30 < bridge> https://www.w3schools.com/sql/ 06:41 < bridge> i fast read it yesterday, how can i combine my existing c++ code with sql ? 06:44 < bridge> DDNetCharacter has m_FreezeEnd field. 06:44 < bridge> https://github.com/ddnet/ddnet/blob/42319546a6d3d98e300405cb11011fcee1332cce/src/game/server/entities/character.cpp#L1250 06:45 < bridge> based on that you should be able to recreate the exact logic the server uses 06:46 < bridge> @stormaxd oh, and you also have m_FreezeStart which might be helpful, idk right now 06:50 < bridge> <__bauxite__> Hey everyone, I'm hoping I might be able to get some help here, I couldn't find answers on the internet, however I came across a blog post by @deen and it led me here. The issue is about small to medium size DDOS attacks on my game server (Valve Source 1 engine game), I'm looking for help to mitigate such attacks. My server is often hit by 50k PPS attacks probably from some "script kiddie", I suppose an entry-level server should in theory be a 07:07 < bridge> I hate this world 07:08 < bridge> 😆 07:09 < bridge> I would first of all check why the server is having issues. 07:09 < bridge> 07:09 < bridge> First thing to check is if the attacks have enough throughput to saturate your connection. If they do then you are in our situation and there isn't much to do, if you can find a cooperative hoster they might let you have filters upstream, that is the only thing that helps that isn't cost prohibitive. You also use Source 1, so I'm guessing Source networking, the protocol is much more supported than our custom solution, you might have better luck wi 07:11 < bridge> <__bauxite__> Nah they're small attacks, not sure how to check why my server is having issues, I'm fairly new to Linux, but I guess them spamming 50k pps at my game port probably doesn't help 07:13 < bridge> It's either CPU overload or network overload 07:15 < bridge> <__bauxite__> Hmm I see, I'll have to look into it, I wonder if I can tell them to ddos me when im testing instead of playing 😂 07:18 < bridge> <__bauxite__> Do you have any suggestions to be able to analyse the situation when the attack occurs (again I'm fairly new to linux so if you could point me in the right direction) 07:19 < bridge> Check `htop` for CPU usage 07:20 < bridge> <__bauxite__> I suppose if it's cpu related I can always pay for a bigger cpu, if network maybe I can do the same? 07:20 < bridge> Also another critical thing is whether the kernel is struggling to deliver the 50k pps or whether there is a defect in the game that's struggling to drop the garbage fast enough 07:21 < bridge> <__bauxite__> I'd like to say there's many defects in the game because it's on a 2006 engine version which never got any of the security and other updates 07:21 < bridge> <__bauxite__> But idk for sure 07:22 < bridge> Problem is network cost scales exponentially for us. Attack cost scales weakly linearly. So you start needing insane amounts of networking just to handle the occasional attack 07:23 < bridge> <__bauxite__> Yeah i can see why it would be more difficult in your situation, fortunately I only run 1 small server for a game literally nobody plays so I'm not even sure why we're getting ddosed in the first place xd 07:24 < bridge> If the game engine is having trouble dropping the packets but not the kernel you can try dropping them in iptables and that should help. 07:24 < bridge> 07:24 < bridge> If the kernel is having trouble delivering the packets you'll need to mess around with kernel options, maybe try an xdp filter or upgrade to a better cpu 07:24 < bridge> It seems to boil down to kids and psycopaths 07:40 < bridge> <__bauxite__> I guess the first step is constructing a set of iptables rules that seems good, then go from there, unfortunately I have limited knowledge of iptables and documentation doesnt seem great, but i'll keep at it, see what happens. I gotta find some way to gather data during the attack that might be helpful, but idk where to start with that yet. 07:41 < bridge> <__bauxite__> I guess the first step is constructing a set of iptables rules that seems good, then go from there, unfortunately I have limited knowledge of iptables and documentation doesnt seem great, but i'll keep at it, see what happens. I gotta find some way to gather data during the attack that might be helpful, but idk where to start with that yet, other than checking the network and cpu usage. 08:00 < bridge> Or there is an opportunity for reflection attacks. And @__bauxite__ is just collateral damage. Or it’s a wider attack and the Hoster is actually the target or something like that. I also find it hard to believe small servers can be targets of ddos. Everything I get some I am saying to my self „I can not be the main target that makes no sense“ :D 08:00 < bridge> Or there is an opportunity for reflection attacks. And @__bauxite__ is just collateral damage. Or it’s a wider attack and the Hoster is actually the target or something like that. I also find it hard to believe small servers can be targets of ddos. Everytime I get some I am saying to my self „I can not be the main target that makes no sense“ :D 08:02 < bridge> morning to the early birds 08:04 < bridge> I personally like using `nload` to look at the amount of traffic but you seem to have those numbers already. Then I can recommend capturing one attack with `tcpdump -w attack.pcap` let that running for a short time during the attack then ctrl+c it. This is something you can then analyse after the fact. Then as fokko pointed out check your cpu usage. If your game server it self has cpu spikes and there is lags in game but your ssh is still smo 08:05 < bridge> It’s also interesting how you are being attacked. Is your game tcp or udp based? Are the IPs spoofed? Is it just a few IPs? Is it a lot of different IPs? Where are the IPs coming from? 08:09 < bridge> Also which port or service is attacked? Is it targeting your game server? Is it doing so with packets that implement the protocol correctly? Can they tell you something about your weak spots? Is it targeting a different port? Could target a website you have running and the game server lagging is just a side effect. 08:22 < bridge> I'd always block everything using host's provided fw and only allow used ports first 08:22 < bridge> Then yes you can check what the attack is exactly by analyzing it 08:24 < bridge> iptables is kinda old and has been replaced by nftables, but if you still use iptables and want to gain a bit of performance you can put your rules in the table mangle, chain PREROUTI'G 08:24 < bridge> PREROUTING\* 08:27 < bridge> Isn't iptables just a frontend for nftables in the kernel nowadays? 08:28 < bridge> iptables is the frontend for netfilter 08:29 < bridge> nftables is netfilter too afaik, but somehow more optimized 08:29 < bridge> from the wiki: `nftables uses mostly the same Netfilter infrastructure as legacy iptables` 08:30 < bridge> https://developers.redhat.com/blog/2017/04/11/benchmarking-nftables 08:30 < bridge> kinda old but still p 08:30 < bridge> kinda old but still up 08:32 < bridge> Hm, I'm fairly sure nftables replaced the iptables part of the netfilter 08:33 < bridge> afaik the kernel part didn't change much (netfilter), only some changes regarding nftables. But nowadays when you use iptables command you're kinda using nftables 08:34 < bridge> if you want to use the good old iptables you have to dpkg-reconfigure & switch to iptables-legacy 08:34 < bridge> (debian) 08:37 < bridge> morning 08:38 < bridge> @learath2 i unmasked amd64 on llvm and all related to get llvm 17 08:38 < bridge> also lld 17 08:38 < bridge> but i dont have lld on path 08:38 < bridge> its weird 08:38 < bridge> oh 08:38 < bridge> i have it today 08:38 < bridge> maybe i needed a restart 08:39 < bridge> ❯ which lld 08:39 < bridge> /usr/lib/llvm/17/bin/lld 08:39 < bridge> ye im sure it setups symlinks or path in some profile thing 08:39 < bridge> @learath2 ah yea well looks like nftables uses a newer kernel infrastructure in which the idea was taken from BPF-like systems 08:39 < bridge> Bash caches executable locations 08:40 < bridge> inspired* 08:40 < bridge> You need to run `hash -someargumentIdontrememberRTFM` 08:40 < bridge> what i mean is, it required a login instead of closing and opening term 08:40 < bridge> xd 08:41 < bridge> Yep, one thing I don't remember though is if the old iptables stuff still exists in the kernel 08:42 < bridge> they do if you switch to the legacy part 08:42 < bridge> if not ig old modules are disabled by default 08:42 < bridge> @jupeyy_keks did u see tcp getting a 40% increase on perfomance on kernel 6.9 opn epyc processors but not intel? 08:42 < bridge> because epyc has separated l3 caches and intel has unified 08:43 < bridge> Kernel 69?? 08:43 < bridge> I have to upgrade 08:44 < bridge> https://www.phoronix.com/news/Linux-6.8-Networking 08:44 < bridge> 6.8* 08:44 < bridge> i mean 08:44 < bridge> sry 08:44 < bridge> Linux 6.8 Network Optimizations Can Boost TCP Performance For Many Concurrent Connections By ~40% 08:45 < bridge> A hell of an improvement especially for the AMD EPYC servers. Kudos to those at Google continuing to push these very enticing low-level kernel optimizations. 08:45 < bridge> https://cdn.discordapp.com/attachments/293493549758939136/1194909880377675836/image.png?ex=65b2118b&is=659f9c8b&hm=3b2a1ff6e6a2f095a7cf9053aa30f435588919a34080e26125bab5f8ae0e5af4& 08:45 < bridge> > As we've seen recently with efforts to drop old/obsolete network drivers, several outdated WiFi drivers were removed for Linux 6.8. Newly-dropped Wifi support include Libertas 16-bit PCMCIA support, Atmel at76c50x drivers, HostAP ISA/PCMCIA style 802.11b driver, zd1201 802.11b USB dongles, Orinoco ISA/PCMCIA 802.11b driver, Aviator/Raytheon driver, Planet WL3501 driver, and the RNDIS USB 802.11b driver. 08:45 < bridge> > 08:45 < bridge> > When it comes to network driver improvements in Linux 6.8, the Intel high-speed NIC driver has added support for temperature and clock information reporting, among other random improvements throughout the many network drivers. NVIDIA Mellanox Ethernet data center switches can also now enjoy firmware updates without a reboot. On the WiFi side there remains ongoing WiFi 7 work and Extremely High Throughput (EHT) improvements. 08:46 < bridge> @learath2 they did this 08:46 < bridge> > "Currently, variable-heavy structs in the networking stack is organized chronologically, logically and sometimes by cache line access. 08:46 < bridge> > 08:46 < bridge> > This patch series attempts to reorganize the core networking stack variables to minimize cacheline consumption during the phase of data transfer. Specifically, we looked at the TCP/IP stack and the fast path definition in TCP." 08:47 < bridge> Yeah, epyc 08:48 < bridge> xd 08:48 < bridge> we should restructure our structs too 08:48 < bridge> kek 08:49 < bridge> Unlikely it would matter for us. We probably wouldn't even notice it with all the lower hanging fruit 09:08 < bridge> minecraft happy about that 09:22 < bridge> :tear: 09:24 < bridge> do they use tcp? 09:24 < bridge> yes 10:08 < bridge> so true 10:10 < bridge> good morning you fiends 10:10 < bridge> https://media.discordapp.net/attachments/1010897757063610448/1170359771795304538/juALdbzB.gif?ex=6558c179&is=65464c79&hm=780cf107919e6bc421219bb031b20d43c59490c6fc43a21cd3afeb752dc6d42d& 10:10 < bridge> how can i narrow the result of pResult->GetString(0) down to standard characters ? (abcd....) and (123456...) 10:11 < bridge> idk if ddnet has any alphanumeric filter or rly and string filter routine 10:12 < bridge> I've created a function for that: 10:12 < bridge> ```c++ 10:12 < bridge> int str_check_special_chars(const char *pStr) 10:12 < bridge> { 10:12 < bridge> while(*pStr) 10:12 < bridge> { 10:12 < bridge> if (!((*pStr >= 'a' && *pStr <= 'z') || (*pStr >= 'A' && *pStr <= 'Z') || (*pStr >= '0' && *pStr <= '9'))) 10:12 < bridge> return 0; 10:12 < bridge> pStr++; 10:12 < bridge> } 10:12 < bridge> return 1; 10:12 < bridge> }``` 10:12 < bridge> you can iterate over it and remove characters that aren't in the ranges of 0x30-0x39, 0x41-0x5A, 0x61-0x7a 10:12 < bridge> damn 10:12 < bridge> quick 10:13 < bridge> idk if ddnet has any alphanumeric filter or rly any string filter routine 10:13 < bridge> it's from my mod, it simply checks a string for containing only alphanumeric characters. if not, it returns 0 10:13 < bridge> do you just copy my problem to chatgpt ? 10:13 < bridge> im sure std has something very quick and brief for this btw 10:14 < bridge> ```c++ 10:14 < bridge> if (str_check_special_chars(aUsername) == 0) 10:14 < bridge> { 10:14 < bridge> pSelf->SendChatTarget(pResult->m_ClientID, "Your username can only consist of letters and numbers"); 10:14 < bridge> return; 10:14 < bridge> }``` 10:14 < bridge> he makes the f-ddrace mod 10:14 < bridge> (from my ConRegister) 10:15 < bridge> i gonna use it for registering stuff too 10:15 < bridge> 👍 10:15 < bridge> imagine asking chtgpt about ddnet codebase lmao 10:16 < bridge> ```cpp 10:16 < bridge> std::string in, out; 10:16 < bridge> std::copy_if (in.begin(), in.end(), std::back_inserter(out), [](char c) { 10:16 < bridge> return std::isalnum(c); 10:16 < bridge> }); 10:16 < bridge> ``` 10:16 < bridge> i'd probably do smth like that 10:16 < bridge> googling failed me in finding a quicker way 10:16 < bridge> Probably works equally as fine 10:16 < bridge> yea 10:16 < bridge> da brevity doe 10:17 < bridge> hm this one just needs its std::isalnum 10:17 < bridge> yea 10:17 < bridge> true 10:18 < bridge> I've decided to adapt to ddnet's system.cpp style 10:18 < bridge> for wat 10:18 < bridge> superior of system.c :troll: 10:18 < bridge> but i really don't feel like making the account system in c++, can some one give me direction in using sql ? 10:18 < bridge> indeed 10:18 < bridge> what do u need direction for 10:18 < bridge> what specifically do u not know how to do 10:19 < bridge> check out mrpg, there is some mysql based account system 10:19 < bridge> everything :justatest: 10:19 < bridge> . 10:21 < bridge> i tiered of making same shit in my every program and function 10:21 < bridge> idk what u mean 10:21 < bridge> that's life 10:22 < bridge> a cant no more make one of these. 10:22 < bridge> ```cpp 10:22 < bridge> char abuff[1001]; 10:22 < bridge> str_format(abuff, sizeof(abuff), 10:22 < bridge> ``` 10:22 < bridge> there are strategies that make it so you rarely have to write duplicate code 10:22 < bridge> oh yeah 10:22 < bridge> such is life 10:23 < bridge> for simple stuff like this you can add an auxiliary buffer higher in scope just for formats & copies, guaranteed that you never access it before setting it, keep a pointer or reference to it, etc 10:23 < bridge> so u can just use the same buffer for all ur string formats & copy them where they're needed 10:23 < bridge> not "all" but a lot 10:24 < bridge> :cammo: 10:24 < bridge> i have never interfaced with sql in ddnet so the implementation details are outside my grasp 10:24 < bridge> i don't imagine it's anything difficult 10:24 < bridge> you have your string query and you get your results 10:24 < bridge> Why not `isalpha`? 10:24 < bridge> sift through them 10:24 < bridge> and continue the tedium of life 10:24 < bridge> checkout CScore code in ddney 10:24 < bridge> idk, made it a long time ago 10:24 < bridge> ddnet 10:25 < bridge> afair it has some sql interaction 10:25 < bridge> is mrpg a mod for ddnet ? 10:25 < bridge> yup 10:25 < bridge> kurosio refactored it a little™ 10:25 < bridge> so better check ddnet code :kek: 10:26 < bridge> where is that boy who said to me use sql, guide me 10:26 < bridge> https://tenor.com/view/dat-boi-frog-unicycle-gif-5480965 10:26 < bridge> rare reference 10:27 < bridge> @kekomonter 10:27 < bridge> help..... 10:27 < bridge> https://github.com/ddnet/ddnet/blob/master/src/game/server/score.cpp 10:30 < bridge> what should i make in dd net. 10:30 < bridge> i am sort of bored 10:38 < bridge> Whut? 10:38 < bridge> did u read 10:39 < bridge> :justatest: 10:39 < bridge> This was my worst words 10:56 < bridge> hi man 10:56 < bridge> :justatest: 10:57 < bridge> I think you can just take from my mode and refactor for your, this will be easiest than my explaining of sql in ddnet code 10:58 < bridge> ok 10:58 < bridge> And my explaining will be hard to understand cuz my english is so bad xd 10:58 < bridge> cool 11:00 < bridge> And my explanation will be hard to understand cuz my english is so bad xd 11:02 < bridge> yup 11:06 < bridge> Ah, I guess I can do that now that I have a bit of time 11:07 < bridge> I wonder if people still care 11:11 < bridge> Yes 11:15 < bridge> Probably. At least I think I would use it 11:33 < bridge> ❤️ 11:35 < bridge> yes 11:44 < bridge> I'd like to see a timer counting it down as a more nerdy option xD 11:45 < bridge> I'd like to see a timer counting it down as a more nerdy option (like with numbers) xD 12:22 < bridge> i want to make folder named "Account" when a server created. where do i need to put this ? 12:22 < bridge> ```cpp 12:22 < bridge> if(!Storage()->FolderExists("Accounts", IStorage::TYPE_SAVE)) 12:22 < bridge> { 12:22 < bridge> Storage()->CreateFolder("Accounts", IStorage::TYPE_SAVE); 12:22 < bridge> } 12:22 < bridge> ``` 12:22 < bridge> i want to make folder named "Accounts" when a server created. where do i need to put this ? 12:22 < bridge> ```cpp 12:22 < bridge> if(!Storage()->FolderExists("Accounts", IStorage::TYPE_SAVE)) 12:22 < bridge> { 12:22 < bridge> Storage()->CreateFolder("Accounts", IStorage::TYPE_SAVE); 12:22 < bridge> } 12:22 < bridge> ``` 12:22 < bridge> Do you know the hierarchy? 12:23 < bridge> Like, where the server is starting (c++ main function) 12:23 < bridge> and how everything is initializing from it? 12:23 < bridge> no, i put it in CServer::Init() but it gave me an segmentation fault at building time 12:23 < bridge> What does it say? 12:24 < bridge> just segmentation fault, nothing else 12:24 < bridge> (my guess: storage is not yet initialized) 12:24 < bridge> do you develop in release mode? 12:25 < bridge> this is the code i use everytime 12:25 < bridge> 12:25 < bridge> $ cmake --build ../build && ./../build/DDNet-Server.exe 12:25 < bridge> holy shit he’s doing it like a barbarian 12:25 < bridge> ok 12:25 < bridge> why 😂 12:26 < bridge> cosmos do it in CStorage ctor 12:26 < bridge> or rather after 12:26 < bridge> immediately after 12:26 < bridge> anyways, fast-forward: I personally create the folder in CGamecontext::OnInit(), but that's up to you where you do it 12:26 < bridge> juts make sure the m_pStorage pointer is actually set 12:26 < bridge> then it should work 12:26 < bridge> yah 12:26 < bridge> im hungry 12:26 < bridge> what to eat 12:26 < bridge> same, gonna do lunch break soon 12:27 < bridge> no home food and nothing is open 12:27 < bridge> ugh 12:28 < bridge> I'm at work, gonna grab something from the chicken truck 12:28 < bridge> sweet 12:28 < bridge> what do u do at work 12:28 < bridge> programming 12:28 < bridge> websites though, using VueJS 12:29 < bridge> frontend and backend 12:29 < bridge> sweet 12:29 < bridge> yea 12:29 < bridge> i should give my website some attention 12:29 < bridge> same 12:29 < bridge> buttoo lazy 12:29 < bridge> admittedly I am slow to pick up on new tech 12:29 < bridge> especially pertaining to the web 12:29 < bridge> it's a pain in the ass anyways 12:30 < bridge> i am using the vanilla stack but I could probably benefit from a css framework 12:30 < bridge> CSS, supporting different browsers, etc 12:30 < bridge> css is fine 12:30 < bridge> at least we were allowed to drop internet explorer support 12:30 < bridge> cuz THATS a pain in the ass 12:30 < bridge> yea 12:31 < bridge> i am so hungry 12:31 < bridge> Ok, gtg grab some food 12:31 < bridge> see you in half an hour 13:00 < bridge> how’s food 13:02 < bridge> was nice 13:02 < bridge> u still hungry? haha 13:02 < bridge> i neglected to start cooking until just now 13:02 < bridge> got rice 13:03 < bridge> and some chicken 13:03 < bridge> :kek: 13:03 < bridge> :justatest: 13:03 < bridge> me rn 13:06 < bridge> i don’t like this kind of chicken… 13:06 < bridge> 🐔 13:07 < bridge> maybe i will use some of this ground beef instead 13:24 < bridge> i added 1 folder and 2 files to the src directory. 13:24 < bridge> now it wont compile 13:24 < bridge> ```bash 13:24 < bridge> [127/135] Linking CXX executable DDNet-Server.exe 13:24 < bridge> FAILED: DDNet-Server.exe 13:24 < bridge> cmd.exe /C "cd . && C:\msys64\ucrt64\bin\c++.exe -O3 -DNDEBUG @CMakeFiles\game-server.rsp -o DDNet- 13:24 < bridge> Server.exe -Wl,--out-implib,libDDNet-Server.dll.a -Wl,--major-image-version,0,--minor-image-version, 13:24 < bridge> 0 && cd ." 13:24 < bridge> C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: 13:24 < bridge> CMakeFiles/game-server.dir/src/game/server/ddracechat.cpp.obj:ddracechat.cpp:(.text+0x54a3): undefi 13:24 < bridge> ned reference to `SkyB::IsStandardString(char const*)' 13:24 < bridge> C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: 13:24 < bridge> CMakeFiles/game-server.dir/src/game/server/ddracechat.cpp.obj:ddracechat.cpp:(.text+0x55a2): undefi 13:24 < bridge> ned reference to `SkyB::IsStandardString(char const*)' 13:24 < bridge> collect2.exe: error: ld returned 1 exit status 13:24 < bridge> [134/135] Building CXX object CMakeFiles/game-client.dir/src/game/editor/editor.cpp.obj 13:24 < bridge> ninja: build stopped: subcommand failed. 13:24 < bridge> ``` 13:26 < bridge> `undefined reference to SkyB::IsStandardString(char const*)` 13:26 < bridge> did you declare it in skyb.h? 13:28 < bridge> this is my value.h file 13:28 < bridge> ```cpp 13:28 < bridge> #ifndef SKYBLOCK_VALUES_H 13:28 < bridge> #define SKYBLOCK_VALUES_H 13:28 < bridge> 13:28 < bridge> //I put all of my values and functions here 13:28 < bridge> namespace SkyB 13:28 < bridge> { 13:28 < bridge> bool IsStandardString(const char *pStr); 13:28 < bridge> } 13:29 < bridge> ``` 13:29 < bridge> and this is the value.cpp file 13:29 < bridge> ```cpp 13:29 < bridge> #include "values.h" 13:29 < bridge> 13:29 < bridge> bool SkyB::IsStandardString(const char *pStr) 13:29 < bridge> { 13:29 < bridge> while(*pStr) 13:29 < bridge> { 13:29 < bridge> if (!((*pStr >= 'a' && *pStr <= 'z') || (*pStr >= 'A' && *pStr <= 'Z') || (*pStr >= '0' && *pStr <= '9'))) 13:29 < bridge> return false; 13:29 < bridge> pStr++; 13:29 < bridge> } 13:29 < bridge> return true; 13:29 < bridge> } 13:29 < bridge> ``` 13:29 < bridge> this is my values.h file 13:29 < bridge> ```cpp 13:29 < bridge> #ifndef SKYBLOCK_VALUES_H 13:29 < bridge> #define SKYBLOCK_VALUES_H 13:29 < bridge> 13:29 < bridge> //I put all of my values and functions here 13:29 < bridge> namespace SkyB 13:30 < bridge> { 13:30 < bridge> bool IsStandardString(const char *pStr); 13:30 < bridge> } 13:30 < bridge> ``` 13:30 < bridge> and this is the values.cpp file 13:30 < bridge> ```cpp 13:30 < bridge> #include "values.h" 13:30 < bridge> 13:30 < bridge> bool SkyB::IsStandardString(const char *pStr) 13:30 < bridge> { 13:30 < bridge> while(*pStr) 13:30 < bridge> { 13:30 < bridge> if (!((*pStr >= 'a' && *pStr <= 'z') || (*pStr >= 'A' && *pStr <= 'Z') || (*pStr >= '0' && *pStr <= '9'))) 13:30 < bridge> return false; 13:30 < bridge> pStr++; 13:30 < bridge> } 13:30 < bridge> return true; 13:30 < bridge> } 13:30 < bridge> ``` 13:30 < bridge> i see on one of the chillerdragon videos, he add something to the cmakelist.txt or something 13:31 < bridge> You need to add the file to cmake ,yes 13:31 < bridge> otherwise it won't be recognized 13:32 < bridge> is CmakeList.txt is auto generated? 13:32 < bridge> no 13:32 < bridge> No 13:32 < bridge> slowdragon 13:32 < bridge> Only if your name is vhllerrdragon 13:32 < bridge> Dude 13:33 < bridge> I in da plane xd 13:33 < bridge> hi vhllerrdragon 13:33 < bridge> I have a shell script that auto generates cmakelists 13:33 < bridge> Fakof xd 13:33 < bridge> where u flying tho 13:33 < bridge> bali 13:33 < bridge> fakof 13:34 < bridge> Ye 13:34 < bridge> have a nice time bro 13:34 < bridge> 17 Hours no \#developer 13:34 < bridge> Don’t spam too much 13:35 < bridge> dont worry, i'll be here to start some conversations on multiple topics so that you can read everything later and look which is actually interesting and which not 13:35 < bridge> thank me later 13:35 < bridge> Dude but the Cmake script is so nice. I wonder if anyone would also like it. Idk how to market it better 13:35 < bridge> Xd 13:35 < bridge> send github link maybe 13:36 < bridge> ChillerDragon/crools/tw\_cmake 13:36 < bridge> Mobile link be like 13:36 < bridge> i cant click 13:36 < bridge> Fakof 13:36 < bridge> where link 🐒 13:36 < bridge> It’s more of a riddle 13:36 < bridge> https://github.com/ChillerDragon/crools/tw_cmake 13:37 < bridge> not found 13:37 < bridge> sounds like we will never get the script 13:37 < bridge> if you're going to foolishly automate the cmakelists you should just glob the source files 13:37 < bridge> idk how he wants to market it better when he 1. doesnt send a link and 2. sends a wrong part of the link 13:37 < bridge> it's a riddle... 13:38 < bridge> Dude I phone and it riddle 13:38 < bridge> so true 13:38 < bridge> ur riddle 13:38 < bridge> I don’t wanna do /master/- 13:38 < bridge> no need 13:38 < bridge> do i need to put it there in a way so it get compiled at correct moment? or just put it there (i am not talking about alphabetically order) 13:38 < bridge> idk what you mean 13:38 < bridge> its a riddle 13:38 < bridge> so true 13:39 < bridge> :thonk: 13:39 < bridge> me rn 13:39 < bridge> you need to put it in the proper category 13:39 < bridge> just search an existing file yours is related or near to and add it next to that 13:39 < bridge> i think the CI will warn you if they are not sorted alphabetically 13:39 < bridge> but it doesn't actually matter for anything but clarity 13:39 < bridge> last warning before self destruction 13:40 < bridge> code will be deleted permanently 13:40 < bridge> ok 13:41 < bridge> Ok riddle wrong 13:41 < bridge> you dont say 13:41 < bridge> https://media.discordapp.net/attachments/928853077593849900/1098329994545082508/F12A3953-F102-4088-BEB1-F68E57F88ECD.gif 13:41 < bridge> Ok my internet ded nvm I market other time 13:42 < bridge> greatest salesman of all time 13:42 < bridge> 📈 13:44 < bridge> im liking this shift from new ppl wanting to make bot clients to ppl making server 13:44 < bridge> also myr also has balls posting in this channel considering 13:44 < bridge> wait til the serverside bot questions come and they start their own client :kek: 13:44 < bridge> macho client or whatever it is called 13:45 < bridge> :think_bot: 13:46 < bridge> https://github.com/lib-crash/lib-teeworlds/blob/master/bin/tw_cmake 13:46 < bridge> ez 13:47 < bridge> bro 13:47 < bridge> Hard riddle 13:47 < bridge> tf is that name 13:47 < bridge> lib crash 13:47 < bridge> i know already what it does 13:47 < bridge> very, very bad marketing 13:47 < bridge> Xd 13:47 < bridge> you need some crash course 13:47 < bridge> on marketing 13:48 < bridge> true 13:48 < bridge> hit me up if you're interested, 5€/h 13:48 < bridge> *(that's marketing my friend)* 13:48 < bridge> meta 13:49 < bridge> :D 13:49 < bridge> i was hoping to reap the benefits of the msys build environment but apparently it uses newlib libc + some cygwin glue for the posix compatibility layer 13:49 < bridge> i was hoping to reap the benefits of the msys build environment in another env but apparently it uses newlib libc + some cygwin glue for the posix compatibility layer 13:49 < bridge> https://cygwin.com/cgit/newlib-cygwin/tree/winsup/cygwin/poll.cc 13:49 < bridge> it's quite nasty 13:49 < bridge> so i couldn't use the ucrt shell to make anything dependent on e.g. 13:49 < bridge> or compile for 32 bit 13:49 < bridge> :feelsbadman: 13:51 < bridge> but i guess it's fine since the only thing in my setup that i actually need the posix compatibility for is distcc and it doesn't really matter which runtime that uses lol 13:52 < bridge> now compile like a charm 13:52 < bridge> great 13:53 < bridge> fokko are u windows 13:55 < bridge> how can i generate one of these SKYBLOCK_VALUES_H for my header ? 13:55 < bridge> wdym 13:55 < bridge> the header guard? 13:55 < bridge> `#pragma once` at the top of ur file 13:55 < bridge> #ifndef SKYBLOCK_VALUES_H 13:55 < bridge> #define SKYBLOCK_VALUES_H 13:56 < bridge> or this, for the very few compilers that don't support `#pragma once` 13:56 < bridge> ```cpp 13:56 < bridge> #ifndef SKYBLOCK_VALUES_H 13:56 < bridge> #define SKYBLOCK_VALUES_H 13:56 < bridge> 13:56 < bridge> your code 13:56 < bridge> 13:56 < bridge> #endif // SKYBLOCK_VALUES_H 13:56 < bridge> ``` 13:56 < bridge> let me try it 13:57 < bridge> do u know what this does 13:58 < bridge> i think it wont allow including a header no more than one time 13:59 < bridge> yes 13:59 < bridge> is it gonna broke the program if you don't put these on your header ? 14:00 < bridge> It could lead to endless inclusions 14:00 < bridge> like 2 file including eachother endlesslz 14:00 < bridge> like 2 file including eachother endlessly 14:00 < bridge> depends 14:00 < bridge> No 14:01 < bridge> it could 14:01 < bridge> it will lead to multiple definition error 14:01 < bridge> and it will fail to compile 14:01 < bridge> that's another issue 14:01 < bridge> that’s the only issue 14:01 < bridge> 🤷‍♂️ 14:01 < bridge> Have you already tried it? ^^' 14:02 < bridge> wdym 14:02 < bridge> yes I’ve used a header guard? 14:02 < bridge> including 2 .h withouth header guards 14:02 < bridge> once including the other 14:02 < bridge> one including the other 14:02 < bridge> endless inclusions is not relevant 14:02 < bridge> there’s no way for it to happen 14:02 < bridge> what 14:03 < bridge> once it attempts to define symbol when there is already one of the same name, it will unconditionally fail on compilation * 14:03 < bridge> and if there are no symbols to be defined, the header does nothing 14:08 < bridge> how old are you ? 14:09 < bridge> 18 why :justatest: 14:10 < bridge> I am 23 and don't know shit 14:10 < bridge> That's not possible anyways 14:10 < bridge> and wouldn't make any sense 14:10 < bridge> wdym 14:10 < bridge> two files can't include each other 14:10 < bridge> it wouldn't make sense no 14:11 < bridge> header guard is exactly what ewan said it is for 14:11 < bridge> header guard is a pretty cool name 14:12 < bridge> he protects ur header 14:12 < bridge> tho i'd recommend using `#pragma once` 14:12 < bridge> brevity 14:12 < bridge> does the same exact thing 14:13 < bridge> yes, I did, chillerdragon. it's very easy ^^ 14:13 < bridge> chillerdrgon 14:13 < bridge> I'm using thunderbird 14:13 < bridge> drunk? 14:13 < bridge> vhillerrdragon 14:14 < bridge> https://cdn.discordapp.com/attachments/293493549758939136/1194992835833905242/image.png?ex=65b25ecd&is=659fe9cd&hm=b2f652ac0b4b282cf1c314e9779e5b2153dc76bd47dfe8884b04453de59b4e17& 14:15 < bridge> https://cdn.discordapp.com/attachments/293493549758939136/1194992897121067018/image.png?ex=65b25edc&is=659fe9dc&hm=0cf93a43cc2b4b0e16dbb935f2bcf3923aba04a8085f8cbc3ede96888b87ede6& 14:15 < bridge> thunderbird rocks 14:15 < bridge> https://cdn.discordapp.com/attachments/293493549758939136/1194992927831760978/image.png?ex=65b25ee3&is=659fe9e3&hm=2683702c29294a8adbe11aa5b70c4b5f37867bc45b90333469946d9b4154d8fc& 14:15 < bridge> https://cdn.discordapp.com/attachments/293493549758939136/1194992976573775882/image.png?ex=65b25eef&is=659fe9ef&hm=0605f6ccde820fef4b6c8bd14eda32aca276b050090f72ca51da3a650661304d& 14:15 < bridge> improper syntax 14:15 < bridge> if that isn't recursive calling idk how to call it 14:15 < bridge> #define B 1 14:15 < bridge> That wasn't the point 14:15 < bridge> look at the logs 14:15 < bridge> and then once you get an *actual valid definition* 14:15 < bridge> then it will fail to compile the second time 14:16 < bridge> again, it's not the point 14:16 < bridge> it literally is 14:16 < bridge> ... 14:16 < bridge> My point was recursive calling being an issue 14:16 < bridge> and you told me that wasn't possible 14:16 < bridge> well. it is 14:16 < bridge> ????? 14:17 < bridge> but yeah I forgor how c macros were 💀 14:17 < bridge> this isn't *doing anything* 14:17 < bridge> it's just erroring 14:17 < bridge> It's not possible for two headers to include each other 14:17 < bridge> that's my whole statement 14:17 < bridge> https://cdn.discordapp.com/attachments/293493549758939136/1194993610630893659/image.png?ex=65b25f86&is=659fea86&hm=60bdf07c5c4c41b99a9fd0847c829fd23f8f75ace27e152d7d4936a8936bd146& 14:18 < bridge> it is and it's an issue xD 14:18 < bridge> Issue = not possible 14:18 < bridge> it doesnt make any sense 14:18 < bridge> fokko 14:18 < bridge> please 14:18 < bridge> read the wohle chat 14:18 < bridge> no u 14:18 < bridge> 🍿 14:18 < bridge> . 14:18 < bridge> there's a PR by c0d3d3v that does this, but it also starts laying out the hud pngs differently for some reason: https://github.com/ddnet/ddnet/pull/6724 14:19 < bridge> @devinci24 yes, it does "prevent" recursive includes, but the point is you don't want that behaviour anyways because you can't include two files into each other 14:19 < bridge> Anyways I already wasted enough time on this 14:19 < bridge> True, you did 14:19 < bridge> indeed 14:19 < bridge> yep 14:19 < bridge> 😂 14:19 < bridge> Good soup 14:20 < bridge> I literally said it as an issue... and a use of header guards... idk why I m getting so much shit for it 14:20 < bridge> mb I guess 14:20 < bridge> Because it's not what it's used for 14:20 < bridge> in headers, you usually only forward-declare. duplicate typedefs and duplicate function forward declarations are fine IIRC, but not duplicate classes/structs? 14:20 < bridge> because you don't do that anyways 14:21 < bridge> i forgot to expand on my * 14:21 < bridge> but yes 14:21 < bridge> that 14:22 < bridge> @devinci24 the header guard is to make sure each header is only included once 14:22 < bridge> You could want to do it if you have class A that needs Class B and vice-versa. 14:22 < bridge> :greenthing: 14:22 < bridge> yy ofc 14:22 < bridge> No 14:23 < bridge> Please stop dreaming up the least likely situations 14:23 < bridge> that's not possible, in that case you would simply declare the one class in the other header as following: 14:23 < bridge> `class CCharacter;` 14:23 < bridge> That way the compiler can resolve that 14:23 < bridge> But you can't include it 14:24 < bridge> Technically it is if only one header forward declares 14:24 < bridge> Mh, should I provide a version that doesn’t touch assets and only does the stars thing? 14:24 < bridge> But you will never do this 14:24 < bridge> @mpft we successfully finished step #1 of annoying chillerdragon when he will come back in 17 hours 14:24 < bridge> So true 14:24 < bridge> that would be much appreciated. reorganizing the assets seems like a thing we don't have the energy for 14:25 < bridge> @heinrich5991 also, do you perhaps have a windows computer you can test the curl-multi patch on? I’m about to push the finished version but can’t test it due to no computer juice 14:25 < bridge> perhaps you could even extract it from the PR, not sure 14:25 < bridge> computer juice = battery? 14:25 < bridge> I could go home and test it there 14:25 < bridge> computer is getting cranky. he needs his juice 14:25 < bridge> i need my juice 14:25 < bridge> and some sleep 14:26 < bridge> i stayed up till 6:30 :feelsbadman: 14:26 < bridge> The only computer capable of running windows in this house does not have a disk 😄 14:26 < bridge> @devinci24 just fyi we (at least i) werent hating on you 14:26 < bridge> ah. I can test it this evening, yes 14:26 < bridge> wdym 14:26 < bridge> cap 14:26 < bridge> ok 14:26 < bridge> i can test now lerato but i would need a memo 14:27 < bridge> No hdd 14:28 < bridge> how are the other ones incapable is more what i was after 14:28 < bridge> arm or something? 14:34 < bridge> The macbook I’m using does not have any more space for a windows installation. The only other laptop in the house has a broken screen 14:35 < bridge> ah 14:43 < bridge> @learath2 it seems it might actually just be the first two commits of said PR? ^^ 14:46 < bridge> if i make a 14:46 < bridge> ```cpp 14:46 < bridge> abuff[2][100]; 14:46 < bridge> ``` 14:46 < bridge> isn't abuff is a pointer to a pointer ? 14:46 < bridge> no 14:46 < bridge> arrays aren't pointers 14:47 < bridge> but when you make abuff[100] abuff is a pointer 14:47 < bridge> no 14:47 < bridge> that's incorrect 14:47 < bridge> sryy 14:47 < bridge> char 14:47 < bridge> C just allows you to use `abuff` the same way as `(&abuff[0])` 14:47 < bridge> i forgot the char 😄 14:47 < bridge> char abuff[100] 14:47 < bridge> this is just some C weirdness 14:48 < bridge> but `abuff` absolutely isn't a pointer 14:48 < bridge> (it's called array/pointer decay, I think) 14:48 < bridge> if i make a 14:48 < bridge> ```cpp 14:48 < bridge> char abuff[2][100]; 14:48 < bridge> ``` 14:48 < bridge> isn't abuff is a pointer to a pointer ? 14:48 < bridge> i fixed it 14:50 < bridge> no, it's an array of arrays 14:50 < bridge> you should get rid of the "an array is a pointer" intuition 14:51 < bridge> it's wrong 14:51 < bridge> if you declare an array, you don't have a pointer any more than when you declare a normal variable 14:51 < bridge> ```c 14:51 < bridge> int a; 14:51 < bridge> int b[2]; 14:51 < bridge> ``` 14:52 < bridge> it's the new standard thing or i was wrong at the beginning ? 14:52 < bridge> this confusion is mostly due to the thinking that char * and char[] are interchangeable but you definitely should not think about them the same way 14:52 < bridge> most beginners guides will refer to the two in mostly the same way, as a “string” 14:52 < bridge> that's not a new standard, this has been the case since the very first standard in 1989 14:52 < bridge> but one is a pointer and one is an array and this should not be forgo no matter what you are doing! 14:52 < bridge> :justatest: 14:52 < bridge> but one is a pointer and one is an array and this should not be forgotten no matter what you are doing! 14:52 < bridge> you can get in lots of trouble mixing them up 14:53 < bridge> you get the pointer to `a` by writing `&a`. you can get a pointer to the first element of `b` by writing `b` or by writing `(&b[0])` 14:53 < bridge> that you can also write `b` instead of `(&b[0])` mostly makes it harder for beginners 14:56 < bridge> you have char[10] 14:56 < bridge> char == pointer to it's first element (&char[0]) 14:56 < bridge> right ? 14:57 < bridge> yes, when you write the array name `char` (bad example, it's a reserved keyword), then the C compiler turns it into `&char[10]` 14:57 < bridge> i have been wrong my whole life 15:00 < bridge> give you the address of it's last element ? 15:00 < bridge> or did you meant &char[0} 15:01 < bridge> yes, when you write the array name `char` (bad example, it's a reserved keyword), then the C compiler turns it into `&char[0]` 15:01 < bridge> yes, my mistake 15:04 < bridge> ```cpp 15:04 < bridge> char abuff[2][100]; 15:04 < bridge> ``` 15:04 < bridge> so this is a pointer to a pointer abuff ? which is gonna be abuff[0][0] ? 15:05 < bridge> ```cpp 15:05 < bridge> char abuff[2][100]; 15:05 < bridge> ``` 15:05 < bridge> so this is a pointer to a pointer abuff ? which is gonna be &abuff[0][0] ? 15:06 < bridge> or && double reference 😂 15:06 < bridge> i think I'm wrong 15:08 < bridge> &abuff[0] 15:10 < bridge> the problem started from this 15:10 < bridge> ```cpp 15:10 < bridge> char **SkyB::GetUserDirPath() 15:10 < bridge> { 15:10 < bridge> IStorage *storage; 15:10 < bridge> char abuff[2][100]; 15:10 < bridge> storage->GetCompletePath(IStorage::TYPE_SAVE, abuff[0], abuff[1], 100); 15:10 < bridge> return abuff; 15:10 < bridge> } 15:10 < bridge> ``` 15:10 < bridge> this is wrong 15:10 < bridge> char abuff[2][100] is a 2d array of characters 15:11 < bridge> an array holding 2 arrays of 100 in this case 15:11 < bridge> there are no implied pointers in the definition of this 2d array alone 15:13 < bridge> if you only need the path, do aBuff[100] and provide it with a literal input 15:15 < bridge> if i have 15:15 < bridge> ```cpp 15:15 < bridge> char abuff[10][10][10][100]; 15:15 < bridge> ``` 15:15 < bridge> they are all pointers except the last 100 chars, am i right ? 15:15 < bridge> I suppose, In the same way that abuff[10] is a pointer 15:16 < bridge> 100 * all the pointers that you created 15:18 < bridge> and abuff is only a pointer to 10 another pointers ? 15:18 < bridge> this isn’t really how i’d think about it 15:19 < bridge> you are allocating 100,000 bytes 15:20 < bridge> you can take pointers to these elements but since the only named variable here is the array itself, the only pointer you can get from it via shorthand without using the reference operator is abuff itself 15:21 < bridge> it is not to say that abuff in itself is a pointer, because it is an array 15:21 < bridge> but using abuff in any manner which requires a pointer will work because it’s shorthand for &abuff[0] 15:30 < bridge> how can i return a two dimension char ? 15:33 < bridge> There are literally no pointers declared here 15:34 < bridge> no, i need both 15:35 < bridge> don't we have 10*10*10 pointers there ? 15:35 < bridge> No 15:35 < bridge> don't we have 10 * 10 * 10 pointers there ? 15:36 < bridge> The label `abuff`, in some situations "decay"s to a poinger to the first element because it's an array 15:36 < bridge> wdym 15:37 < bridge> It's a special situation when `abuff` is used in some expressions. In those situations the array "turns into" a pointer to it's first element 15:38 < bridge> There are no pointers declared by `char abuff[10][10]`. You declared 10 arrays of arrays of 10 characters 15:39 < bridge> consider a function which takes a char * and you have a char[]. basically every str_ function in ddnet, right? 15:39 < bridge> Yet when you pass `abuff` into a function for example, it will "decay"/"turn into" a pointer to it's first element 15:41 < bridge> i don't get this, how they are not pointers, you say they are all char's ? 15:41 < bridge> they must be array of 10 pointer's which they each gonna point to another array of 10 pointers 15:42 < bridge> anything except this is not making sense 15:44 < bridge> you are basically doing abuff[100000] and all of the extra [] are just doing a bit of handy math to put you at the right index 15:44 < bridge> and in some situations abuff is contextual equivalent to &abuff[0] 15:44 < bridge> that’s all 15:45 < bridge> and in some situations abuff is contextually equivalent to &abuff[0] 15:46 < bridge> and what type they storing ? a char ? 15:46 < bridge> yes 15:46 < bridge> doesn’t really matter the type 15:48 < bridge> let me go to the c++ community, i can't sleep tonight 15:49 < bridge> xd 15:50 < bridge> probably don’t 15:51 < bridge> return char * and know what it really is on the receiving end or create a custom type 15:51 < bridge> but it’s a little unusual 15:52 < bridge> i also think you’re misunderstanding IStorage::GetCompletePath 15:53 < bridge> the first string, pDir is the path name to get (e.g. “skins”) and the second, pBuffer is the output buffer to plop the complete path into (e.g. C:\Users\ewan\AppData\Roaming\DDNet\skins) 15:54 < bridge> trivial functions and stuff in the libc will specify input/output by name but you can usually tell by whether or not the argument is marked as const 15:54 < bridge> const char * has to be input 15:54 < bridge> char * is usually output unless the author forgot to make it const which happens sometimes 15:58 < bridge> i can't stand this, i was wrong so many years 15:58 < bridge> it’s alright 15:59 < bridge> when you are new to programming you constantly look back and see how bad your code was just a short time ago 15:59 < bridge> it just means you’re learning 15:59 < bridge> yes 15:59 < bridge> this is good 15:59 < bridge> learning W 16:04 < bridge> but i can't access it directly 16:04 < bridge> 16:04 < bridge> ```bash 16:04 < bridge> error: cannot call member function 'virtual void IStorage::GetCompletePath(int, const char*, char*, unsigned int)' witho 16:04 < bridge> ut object 16:04 < bridge> ``` 16:04 < bridge> nono 16:04 < bridge> still call it with your IStorage * instance 16:04 < bridge> just use the arguments correctly 16:04 < bridge> it is not static 16:05 < bridge> if it was static i could call it directly without object ? 16:05 < bridge> yes 16:05 < bridge> wow 16:06 < bridge> but it can’t access any members or non static methods 16:06 < bridge> it’s basically a normal function 16:06 < bridge> thank you man 16:06 < bridge> np 16:06 < bridge> today i did not cod that much but i leaned a lot 16:06 < bridge> awesome 16:07 < bridge> :poggers2: 16:07 < bridge> learning is awesome 16:19 < bridge> why you can't get screenshots with windows tools on ddnet ? 16:20 < bridge> you can 16:20 < bridge> i remember it wasn't the problem before 16:20 < bridge> if you’re in fullscreen then you have to tab in or do it twice 16:21 < bridge> since its a fullscreen window it doesn’t interact with dwm/the shell at all except for the thumbnail 16:21 < bridge> and since the screenshot apis work through dwm it can’t do it properly 16:21 < bridge> i assume it asks for the thumbnail but not before already taking the screenshot 16:22 < bridge> u can look it up in feedback hub there’s probably something about it there 16:22 < bridge> it's strange, now i can screenshots 16:22 < bridge> you can use desktop fullscreen and it’ll be mostly the same minus a few extra steps for inputs to get to the game & frames to get to the screen 16:23 < bridge> but screenshots should work 16:25 < bridge> i have to sleep 16:25 < bridge> gn 16:27 < bridge> but screenshots with shareX is weird, 16:31 < bridge> It's been 7 hours and packages are still emerging 😬 18:23 < bridge> the compiler gives me this 18:23 < bridge> ```bash 18:23 < bridge> CMakeFiles/game-server.dir/src/game/server/ddracechat.cpp.obj:ddracechat.cpp:(.bss+0x0): multiple d 18:23 < bridge> efinition of `SkyB::myint 18:23 < bridge> ``` 18:23 < bridge> it's not just ddracechat.cpp, it's on everywhere i included my header (values.h) 18:23 < bridge> 18:23 < bridge> and this i my header: 18:23 < bridge> ```cpp 18:23 < bridge> #ifndef SKYBLOCK_VALUES_H 18:23 < bridge> #define SKYBLOCK_VALUES_H 18:23 < bridge> 18:23 < bridge> //I put all of my values and functions here 18:23 < bridge> namespace SkyB 18:23 < bridge> { 18:23 < bridge> static constexpr unsigned int MAXIMUM_USERNAME_LENGTH = 120; 18:23 < bridge> static constexpr unsigned int MAXIMUM_PASSWORD_LENGTH = 120; 18:23 < bridge> static constexpr unsigned int MINIMUM_USERNAME_LENGTH = 6; 18:23 < bridge> static constexpr unsigned int MINIMUM_PASSWORD_LENGTH = 6; 18:23 < bridge> 18:23 < bridge> int myint; 18:23 < bridge> 18:23 < bridge> bool IsStandardString(const char *pStr); 18:23 < bridge> char *GetUserDirPath(); 18:23 < bridge> } 18:23 < bridge> 18:24 < bridge> #endif //SKYBLOCK_VALUES_H 18:24 < bridge> ``` 18:24 < bridge> 18:24 < bridge> if i remove 18:24 < bridge> ```cpp 18:25 < bridge> ddnet 18:25 < bridge> ddnet 18:25 < bridge> ddnet 18:25 < bridge> ddnet 18:25 < bridge> ddnet 18:25 < bridge> HI 18:25 < bridge> what is happening ? 🙂 18:25 < bridge> i felt it 18:26 < bridge> i tried #pragma once 18:26 < bridge> no luck 18:27 < bridge> is this 100% the whole file? 18:27 < bridge> yes and there is another file: values.cpp 18:27 < bridge> why do you use namespace 18:28 < bridge> but then non static variables 18:28 < bridge> maybe u meant extern int? 18:28 < bridge> bcs what you do there makes no sense in my brain 18:29 < bridge> it's more organised in my opinion 18:29 < bridge> i am surprised cpp even allows this 18:29 < bridge> i cannot imagine any case where this ever makes sense 18:30 < bridge> well ok 18:30 < bridge> cpp doesnt know about headers 18:30 < bridge> so it's basically just a global variable 18:30 < bridge> use extern int 18:30 < bridge> then it works 18:30 < bridge> define the int then in ANY cpp file 18:31 < bridge> actually this is the first time i using namespace in my life 18:32 < bridge> u can do the exact same using a class 18:32 < bridge> just add public 18:32 < bridge> classes kind of are name spaces too xd 18:33 < bridge> but inside a class u'd need a static function 18:33 < bridge> then it's a class function that works without a object 18:33 < bridge> You can just create component system like in client, but in server, and create class like CAuth. Or create class CSkyB, add hooks for main game events, add m_SkyB in CGameContext and call hooks from CSkyB 18:35 < bridge> @mamad_melanin #1 never use global variables 18:35 < bridge> #2 don't listen to ppl with dark green name tags that say otherwise 18:35 < bridge> #3 don't use globals 18:35 < bridge> xd 18:35 < bridge> global variables are the origin of all evilness 18:36 < bridge> why did you mentioned ddnet 5 times ? 18:36 < bridge> do you know the famous quote from Einstein? 18:36 < bridge> 18:36 < bridge> "Don't use global variables, bro, trust me" 18:36 < bridge> oh yes 18:37 < bridge> i dunno. that was my entry song for today 18:37 < bridge> i see it from another Einstein tho 18:37 < bridge> I am twostone 18:37 < bridge> and jao is too stoned 18:42 < bridge> but why it's not allowing me to do it, it's in a namespace 18:44 < bridge> bcs that's not how it works 18:44 < bridge> for ever global variable, it will create a symbol 18:44 < bridge> 18:44 < bridge> and if u do that in a header without extern, it will create many global variables 18:44 < bridge> and then it cannot say which one you meant 18:45 < bridge> imagine header includes literally as text replacements 18:45 < bridge> and then imagine all cpp files that include this header have this global variable 18:45 < bridge> when linking u have the same global var many times 18:46 < bridge> i can't explain it better 18:46 < bridge> ask chatgpt 😏 18:46 < bridge> i get it now 19:26 < bridge> the image i used for my passwords database just got deleted after being on the same place in internet for focking 3 years 19:26 < bridge> :pepeW: 19:29 < bridge> post it here 19:30 < bridge> no nsfw here 😬 19:30 < bridge> 😏 19:30 < bridge> and it will get compressed by discord anyways 22:13 < bridge> Does anyone know how those player information of 0.7 Teeworlds servers are done by the ddnet master server? 22:16 < bridge> it seems like spectating players are shown as is_player=true while ingame players are shown as is_player=false 22:16 < bridge> on 0.7 22:16 < bridge> shouldn't it be the other way around? 23:58 < bridge> :justatest: