Developers Brainstorming
Ideas for game server detection:
To know the ideal, universal way to detect the server for all games it'll be needed to have as much as possible examples on this page so we can figure it out.
Check for all connections of the process with netstat and then use tcpdump for UDP.
Example:
netstat:
udp 0 0 0.0.0.0:38397 0.0.0.0:* 5939/mumble -> local port 38397
tcpdump:
22:55:18.216848 IP 192.168.1.6.38397 > 85.214.87.101.64738: UDP, length 101
22:55:18.239391 IP 192.168.1.6.38397 > 85.214.87.101.64738: UDP, length 83
You exactly know which remote address it is!
Currently working games
In order to be able to determine if the server detection works and has a mature code we need test results. Below are the current test results and their state.
Working games: Wolfenstein: Enemy Territory Enemy Territory: Quake Wars Quake Live Non-working games: Games running using Wine (WIP)
Wolfenstein: Enemy Territory
warren@warren-desktop:~$ netstat -tuanp | grep et.x86 (Tous les processus ne peuvent être identifiés, les infos sur les processus non possédés ne seront pas affichées, vous devez être root pour les voir toutes.) udp 0 0 0.0.0.0:27960 0.0.0.0:* 6173/et.x86 warren@warren-desktop:~$ warren@warren-desktop:~$ tcpdump -c 5 -f -n tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes 09:07:28.790061 IP 88.197.174.175.27960 > 63.211.110.136.27960: UDP, length 28 09:07:28.845063 IP 88.197.174.175.27960 > 63.211.110.136.27960: UDP, length 28 09:07:28.873263 IP 63.211.110.136.27960 > 88.197.174.175.27960: UDP, length 984 09:07:28.900073 IP 88.197.174.175.27960 > 63.211.110.136.27960: UDP, length 28 09:07:28.955178 IP 88.197.174.175.27960 > 63.211.110.136.27960: UDP, length 28 5 packets captured 5 packets received by filter 0 packets dropped by kernel warren@warren-desktop:~$
Problem case: Enemy Territory: Quake Wars
tcp 0 0 88.197.174.164:57278 69.87.248.250:3074 ESTABLISHED 26553/etqw-rthread. tcp 0 0 88.197.174.164:38420 69.87.248.252:3074 CLOSE_WAIT 26553/etqw-rthread. udp 0 0 0.0.0.0:44909 0.0.0.0:* 26553/etqw-rthread. udp 0 0 0.0.0.0:54398 0.0.0.0:* 26553/etqw-rthread. udp 0 0 0.0.0.0:3074 0.0.0.0:* 26553/etqw-rthread.
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes 14:36:52.504193 IP 88.197.174.164.44909 > 78.41.115.234.27733: UDP, length 37 14:36:52.521039 IP 88.197.174.164.44909 > 78.41.115.234.27733: UDP, length 37 14:36:52.554047 IP 88.197.174.164.44909 > 78.41.115.234.27733: UDP, length 37 14:36:52.558195 IP 78.41.115.234.27733 > 88.197.174.164.44909: UDP, length 210 14:36:52.586039 IP 88.197.174.164.44909 > 78.41.115.234.27733: UDP, length 37 5 packets captured 5 packets received by filter 0 packets dropped by kernel
Make gdb logging automatically:
#!/bin/bash TIME=`date +%F-%H%M%S` LOG="$HOME/Documents/Gfire/logs/pidgin-db-${TIME}.log" exec gdb -batch-silent \ -ex 'set logging overwrite on' \ -ex "set logging file ${LOG}" \ -ex 'set logging on' \ -ex 'handle all pass nostop print' \ -ex 'handle SIGCHLD pass nostop noprint' \ -ex 'handle SIGSEGV pass stop print' \ -ex 'set pagination 0' \ -ex 'run' \ -ex 'backtrace full' \ -ex 'info registers' \ -ex 'thread apply all backtrace' \ -ex 'continue' \ --args pidgin \ < /dev/null
Edit the path where the log should be saved and you should start pidgin always this way to be sure that you don't miss any bug.
Idea for a coding convention
- Using glib if possible. Mixing it with stdlib makes no sense.
- Creating functions for accessing data types (compare with glib; get closer to OOP) like at least "gfire_data *gfire_data_create();" and "void gfire_data_free(gfire_data *p_data);"
- Splitting the code in one header/source file combination per task/struct (gfire_data.c/h, gfire_buddy.c/h, purple_interface.c/h, chat.c/h, clan.c/h, game_detection.c/h, ...)
- No warnings (i.e. means no "guint32 val = get_val(231);") :)
- Using const whenever no change to the variable is needed
- Using "//" for single line comments; "/**/" for multiline comments
Example header and source file
/* Copyright note */ #ifndef _HEADER_H #define _HEADER_H #include <include_file.h> #define A "a" typedef struct _i_am_a_struct { gchar *data1; // short description of data1 guint32 data2; // short description of data2 } i_am_a_struct; // Required prototypes void i_am_a_function(const guint32 p_name); #endif // _HEADER_H
/* Copyright note */ #include <header.h> // This function does actually nothing void i_am_a_function(const guint32 p_name) { guint32 game_id = 0; gchar *game_name = NULL; if(!p_name) return; game_name = g_strdup_printf("Game Name Num: %u", p_name); game_id = g_strlen(game_name); if(game_name) g_free(game_name); }