/** * Load all translations that we know of. * @return Container with all (compiled) translations. */ GameStrings *LoadTranslations() { const GameInfo *info = Game::GetInfo(); char filename[512]; strecpy(filename, info->GetMainScript(), lastof(filename)); char *e = strrchr(filename, PATHSEPCHAR); if (e == NULL) return NULL; e++; // Make 'e' point after the PATHSEPCHAR strecpy(e, "lang" PATHSEP "english.txt", lastof(filename)); if (!FioCheckFileExists(filename, GAME_DIR)) return NULL; GameStrings *gs = new GameStrings(); try { *gs->raw_strings.Append() = ReadRawLanguageStrings(filename); /* Scan for other language files */ LanguageScanner scanner(gs, filename); strecpy(e, "lang" PATHSEP, lastof(filename)); size_t len = strlen(filename); const char *tar_filename = info->GetTarFile(); TarList::iterator iter; if (tar_filename != NULL && (iter = _tar_list[GAME_DIR].find(tar_filename)) != _tar_list[GAME_DIR].end()) { /* The main script is in a tar file, so find all files that * are in the same tar and add them to the langfile scanner. */ TarFileList::iterator tar; FOR_ALL_TARS(tar, GAME_DIR) { /* Not in the same tar. */ if (tar->second.tar_filename != iter->first) continue; /* Check the path and extension. */ if (tar->first.size() <= len || tar->first.compare(0, len, filename) != 0) continue; if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue; scanner.AddFile(tar->first.c_str(), 0, tar_filename); } } else { /* Scan filesystem */ scanner.Scan(filename); } gs->Compile(); return gs; } catch (...) {
/* virtual */ char *ReadLine(char *buffer, const char *last) { if (this->p == this->end) return NULL; strecpy(buffer, *this->p, last); this->p++; return buffer; }
static void optionsinit(char* s) { strecpy(oargb, oargb+sizeof(oargb), s); oargblen = strlen(oargb); oargc = tokenize(oargb, oargv, nelem(oargv)-1); oargv[oargc] = nil; }
static int setuser(char *arg) { char *p; strcpy(box, "/mail/box/"); strecpy(box+strlen(box), box+sizeof box-7, arg); strcpy(cbox, box); cleanname(cbox); if(strcmp(cbox, box) != 0) return senderr("bad mailbox name"); strcat(box, "/mbox"); strecpy(user, user+sizeof user, arg); if(p = strchr(user, '/')) *p = '\0'; return 0; }
void Win32SetCurrentLocaleName(const char *iso_code) { /* Convert the iso code into the format that windows expects. */ char iso[16]; if (strcmp(iso_code, "zh_TW") == 0) { strecpy(iso, "zh-Hant", lastof(iso)); } else if (strcmp(iso_code, "zh_CN") == 0) { strecpy(iso, "zh-Hans", lastof(iso)); } else { /* Windows expects a '-' between language and country code, but we use a '_'. */ strecpy(iso, iso_code, lastof(iso)); for (char *c = iso; *c != '\0'; c++) { if (*c == '_') *c = '-'; } } MultiByteToWideChar(CP_UTF8, 0, iso, -1, _cur_iso_locale, lengthof(_cur_iso_locale)); }
virtual EventState OnKeyPress(uint16 key, uint16 keycode) { EventState state = ES_NOT_HANDLED; if (this->HandleEditBoxKey(AID_WIDGET_BREAK_STR_EDIT_BOX, key, keycode, state) != HEBR_NOT_FOCUSED) { /* Save the current string to static member so it can be restored next time the window is opened */ strecpy(this->break_string, this->edit_str_buf, lastof(this->break_string)); } return state; }
/** * Dump the available debug facility names in the help text. * @param buf Start address for storing the output. * @param last Last valid address for storing the output. * @return Next free position in the output. */ char *DumpDebugFacilityNames(char *buf, char *last) { size_t length = 0; for (const DebugLevel *i = debug_level; i != endof(debug_level); ++i) { if (length == 0) { buf = strecpy(buf, "List of debug facility names:\n", last); } else { buf = strecpy(buf, ", ", last); length += 2; } buf = strecpy(buf, i->name, last); length += strlen(i->name); } if (length > 0) { buf = strecpy(buf, "\n\n", last); } return buf; }
/** * Generates Dutch town name from given seed. * @param buf output buffer * @param seed town name seed * @param last end of buffer */ static char *MakeDutchTownName(char *buf, const char *last, uint32 seed) { /* optional first segment */ int i = SeedChanceBias(0, lengthof(_name_dutch_1), seed, 50); if (i >= 0) buf = strecpy(buf, _name_dutch_1[i], last); /* mandatory middle segments including option of hardcoded name */ if (SeedChance(6, 9, seed) > 4) { buf = strecpy(buf, _name_dutch_2[SeedChance( 9, lengthof(_name_dutch_2), seed)], last); } else { buf = strecpy(buf, _name_dutch_3[SeedChance( 9, lengthof(_name_dutch_3), seed)], last); buf = strecpy(buf, _name_dutch_4[SeedChance(12, lengthof(_name_dutch_4), seed)], last); } buf = strecpy(buf, _name_dutch_5[SeedChance(15, lengthof(_name_dutch_5), seed)], last); return buf; }
/** * Clone the custom name of a vehicle, adding or incrementing a number. * @param src Source vehicle, with a custom name. * @param dst Destination vehicle. */ static void CloneVehicleName(const Vehicle *src, Vehicle *dst) { char buf[256]; /* Find the position of the first digit in the last group of digits. */ size_t number_position; for (number_position = strlen(src->name); number_position > 0; number_position--) { /* The design of UTF-8 lets this work simply without having to check * for UTF-8 sequences. */ if (src->name[number_position - 1] < '0' || src->name[number_position - 1] > '9') break; } /* Format buffer and determine starting number. */ int num; byte padding = 0; if (number_position == strlen(src->name)) { /* No digit at the end, so start at number 2. */ strecpy(buf, src->name, lastof(buf)); strecat(buf, " ", lastof(buf)); number_position = strlen(buf); num = 2; } else { /* Found digits, parse them and start at the next number. */ strecpy(buf, src->name, lastof(buf)); buf[number_position] = '\0'; char *endptr; num = strtol(&src->name[number_position], &endptr, 10) + 1; padding = endptr - &src->name[number_position]; } /* Check if this name is already taken. */ for (int max_iterations = 1000; max_iterations > 0; max_iterations--, num++) { /* Attach the number to the temporary name. */ seprintf(&buf[number_position], lastof(buf), "%0*d", padding, num); /* Check the name is unique. */ if (IsUniqueVehicleName(buf)) { dst->name = strdup(buf); break; } } /* All done. If we didn't find a name, it'll just use its default. */ }
void oserrstr(void) { char *p; if((p = strerror(errno)) != nil) strecpy(up->errstr, up->errstr+ERRMAX, p); else snprint(up->errstr, ERRMAX, "unix error %d", errno); }
void setupuser(AuthInfo *ai) { Waitmsg *w; int pid; if(ai){ strecpy(username, username+sizeof username, ai->cuid); if(auth_chuid(ai, nil) < 0) bye("user auth failed: %r"); auth_freeAI(ai); }else strecpy(username, username+sizeof username, getuser()); if(newns(username, 0) < 0) bye("user login failed: %r"); /* * hack to allow access to outgoing smtp forwarding */ enableForwarding(); snprint(mboxDir, MboxNameLen, "/mail/box/%s", username); if(myChdir(mboxDir) < 0) bye("can't open user's mailbox"); switch(pid = fork()){ case -1: bye("can't initialize mail system"); break; case 0: execl("/bin/upas/fs", "upas/fs", "-np", nil); _exits("rob1"); _exits(0); break; default: break; } if((w=wait()) == nil || w->pid != pid || w->msg[0] != '\0') bye("can't initialize mail system"); free(w); }
/** * Register a driver internally, based on its name. * @param name the name of the driver. * @param type the type of driver to register * @param priority the priority; how badly do we want this as default? * @note an assert() will be trigger if 2 driver with the same name try to register. */ void DriverFactoryBase::RegisterDriver(const char *name, Driver::Type type, int priority) { /* Don't register nameless Drivers */ if (name == NULL) return; this->name = strdup(name); this->type = type; this->priority = priority; /* Prefix the name with driver type to make it unique */ char buf[32]; strecpy(buf, GetDriverTypeName(type), lastof(buf)); strecpy(buf + 5, name, lastof(buf)); const char *longname = strdup(buf); std::pair<Drivers::iterator, bool> P = GetDrivers().insert(Drivers::value_type(longname, this)); assert(P.second); }
static void readCmdPart(char *file, char ***pcmd, int *pncmd) { char buf[1024+1], *f[1024]; char tbuf[1024]; int nf; int i, fd, n; char **cmd, *p; int ncmd; cmd = *pcmd; ncmd = *pncmd; if((fd = open(file, OREAD)) < 0) sysfatal("open %s: %r", file); if(seek(fd, 127*1024, 0) != 127*1024) sysfatal("seek %s 127kB: %r", file); n = readn(fd, buf, sizeof buf-1); if(n == 0) sysfatal("short read of %s at 127kB", file); if(n < 0) sysfatal("read %s: %r", file); buf[n] = 0; if(memcmp(buf, "fossil config\n", 6+1+6+1) != 0) sysfatal("bad config magic in %s", file); nf = getfields(buf+6+1+6+1, f, nelem(f), 1, "\n"); for(i=0; i<nf; i++){ if(f[i][0] == '#') continue; cmd = vtMemRealloc(cmd, (ncmd+1)*sizeof(char*)); /* expand argument '*' to mean current file */ if((p = strchr(f[i], '*')) && (p==f[i]||isspace(p[-1])) && (p[1]==0||isspace(p[1]))){ memmove(tbuf, f[i], p-f[i]); strecpy(tbuf+(p-f[i]), tbuf+sizeof tbuf, file); strecpy(tbuf+strlen(tbuf), tbuf+sizeof tbuf, p+1); f[i] = tbuf; } cmd[ncmd++] = vtStrDup(f[i]); } close(fd); *pcmd = cmd; *pncmd = ncmd; }
/** * Appends characters from one string to another. * * Appends the source string to the destination string with respect of the * terminating null-character and and the last pointer to the last element * in the destination buffer. If the last pointer is set to NULL no * boundary check is performed. * * @note usage: strecat(dst, src, lastof(dst)); * @note lastof() applies only to fixed size arrays * * @param dst The buffer containing the target string * @param src The buffer containing the string to append * @param last The pointer to the last element of the destination buffer * @return The pointer to the terminating null-character in the destination buffer */ char *strecat(char *dst, const char *src, const char *last) { assert(dst <= last); while (*dst != '\0') { if (dst == last) return dst; dst++; } return strecpy(dst, src, last); }
/* virtual */ void BaseNetworkContentDownloadStatusWindow::OnDownloadProgress(const ContentInfo *ci, int bytes) { if (ci->id != this->cur_id) { strecpy(this->name, ci->filename, lastof(this->name)); this->cur_id = ci->id; this->downloaded_files++; } this->downloaded_bytes += bytes; this->SetDirty(); }
/** * Frees memory used for this->name */ DriverFactoryBase::~DriverFactoryBase() { if (this->name == NULL) return; /* Prefix the name with driver type to make it unique */ char buf[32]; strecpy(buf, GetDriverTypeName(type), lastof(buf)); strecpy(buf + 5, this->name, lastof(buf)); Drivers::iterator it = GetDrivers().find(buf); assert(it != GetDrivers().end()); const char *longname = (*it).first; GetDrivers().erase(it); free((void *)longname); if (GetDrivers().empty()) delete &GetDrivers(); free((void *)this->name); }
char *GRFTownNameGenerate(char *buf, uint32 grfid, uint16 gen, uint32 seed, const char *last) { strecpy(buf, "", last); for (GRFTownName *t = _grf_townnames; t != NULL; t = t->next) { if (t->grfid == grfid) { assert(gen < t->nb_gen); buf = RandomPart(buf, t, seed, t->id[gen], last); break; } } return buf; }
char* getuser(void) { static char user[64]; struct passwd *pw; pw = getpwuid(getuid()); if(pw == nil) return "none"; strecpy(user, user+sizeof user, pw->pw_name); return user; }
/** Run the dummy AI and let it generate an error message. */ void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type) { /* We want to translate the error message. * We do this in three steps: * 1) We get the error message */ char error_message[1024]; GetString(error_message, string, lastof(error_message)); /* Make escapes for all quotes and slashes. */ char safe_error_message[1024]; char *q = safe_error_message; for (const char *p = error_message; *p != '\0' && q < lastof(safe_error_message) - 2; p++, q++) { if (*p == '"' || *p == '\\') *q++ = '\\'; *q = *p; } *q = '\0'; /* 2) We construct the AI's code. This is done by merging a header, body and footer */ char dummy_script[4096]; char *dp = dummy_script; dp += seprintf(dp, lastof(dummy_script), "class Dummy%s extends %sController {\n function Start()\n {\n", type, type); /* As special trick we need to split the error message on newlines and * emit each newline as a separate error printing string. */ char *newline; char *p = safe_error_message; do { newline = strchr(p, '\n'); if (newline != NULL) *newline = '\0'; dp += seprintf(dp, lastof(dummy_script), " %sLog.Error(\"%s\");\n", type, p); p = newline + 1; } while (newline != NULL); dp = strecpy(dp, " }\n}\n", lastof(dummy_script)); /* 3) We translate the error message in the character format that Squirrel wants. * We can use the fact that the wchar string printing also uses %s to print * old style char strings, which is what was generated during the script generation. */ const SQChar *sq_dummy_script = dummy_script; /* And finally we load and run the script */ sq_pushroottable(vm); if (SQ_SUCCEEDED(sq_compilebuffer(vm, sq_dummy_script, strlen(sq_dummy_script), "dummy", SQTrue))) { sq_push(vm, -2); if (SQ_SUCCEEDED(sq_call(vm, 1, SQFalse, SQTrue))) { sq_pop(vm, 1); return; } } NOT_REACHED(); }
char* stripdot(char *s) { static char buf[64]; char *p; strecpy(buf, buf+sizeof buf, s); p = strrchr(buf, '.'); if(p) *p = 0; return buf; }
static int32_t cecwrite(Chan *c, void *a, int32_t n, int64_t mm) { Proc *up = externup(); Cmdbuf *cb; Cmdtab *cp; if(c->qid.path == Qctl){ cb = parsecmd(a, n); if(waserror()){ free(cb); nexterror(); } cp = lookupcmd(cb, ceccmd, nelem(ceccmd)); switch(cp->index){ case CMsetname: strecpy(name, name+sizeof name-1, cb->f[1]); break; case CMtraceon: tflag = 1; break; case CMtraceoff: tflag = 0; break; case CMsetpasswd: strcpy(passwd, cb->f[1]); break; case CMcecon: cecon(cb->f[1]); break; case CMcecoff: cecoff(cb->f[1]); break; case CMsetshelf: shelf = atoi(cb->f[1]); break; case CMwrite: cecputs((char*)a+6,n-6); break; case CMreset: rst(connidx(atoi(cb->f[1]))); break; default: cmderror(cb, "bad control message"); break; } free(cb); poperror(); return n; } error(Egreg); return 0; }
/** * Generates Italian town name from given seed. * @param buf output buffer * @param seed town name seed * @param last end of buffer */ static char *MakeItalianTownName(char *buf, const char *last, uint32 seed) { if (SeedModChance(0, 6, seed) == 0) { // real city names return strecpy(buf, _name_italian_real[SeedModChance(4, lengthof(_name_italian_real), seed)], last); } static const char * const mascul_femin_italian[] = { "o", "a", }; if (SeedModChance(0, 8, seed) == 0) { // prefix buf = strecpy(buf, _name_italian_pref[SeedModChance(11, lengthof(_name_italian_pref), seed)], last); } uint i = SeedChance(0, 2, seed); if (i == 0) { // masculine form buf = strecpy(buf, _name_italian_1m[SeedModChance(4, lengthof(_name_italian_1m), seed)], last); } else { // feminine form buf = strecpy(buf, _name_italian_1f[SeedModChance(4, lengthof(_name_italian_1f), seed)], last); } if (SeedModChance(3, 3, seed) == 0) { buf = strecpy(buf, _name_italian_2[SeedModChance(11, lengthof(_name_italian_2), seed)], last); buf = strecpy(buf, mascul_femin_italian[i], last); } else { buf = strecpy(buf, _name_italian_2i[SeedModChance(16, lengthof(_name_italian_2i), seed)], last); } if (SeedModChance(15, 4, seed) == 0) { if (SeedModChance(5, 2, seed) == 0) { // generic suffix buf = strecpy(buf, _name_italian_3[SeedModChance(4, lengthof(_name_italian_3), seed)], last); } else { // river name suffix buf = strecpy(buf, _name_italian_river1[SeedModChance(4, lengthof(_name_italian_river1), seed)], last); buf = strecpy(buf, _name_italian_river2[SeedModChance(16, lengthof(_name_italian_river2), seed)], last); } } return buf; }
/** * Generates Turkish town name from given seed. * @param buf output buffer * @param seed town name seed * @param last end of buffer */ static char *MakeTurkishTownName(char *buf, const char *last, uint32 seed) { uint i = SeedModChance(0, 5, seed); switch (i) { case 0: buf = strecpy(buf, _name_turkish_prefix[SeedModChance( 2, lengthof(_name_turkish_prefix), seed)], last); /* middle segment */ buf = strecpy(buf, _name_turkish_middle[SeedModChance( 4, lengthof(_name_turkish_middle), seed)], last); /* optional suffix */ if (SeedModChance(0, 7, seed) == 0) { buf = strecpy(buf, _name_turkish_suffix[SeedModChance( 10, lengthof(_name_turkish_suffix), seed)], last); } break; case 1: case 2: buf = strecpy(buf, _name_turkish_prefix[SeedModChance( 2, lengthof(_name_turkish_prefix), seed)], last); buf = strecpy(buf, _name_turkish_suffix[SeedModChance( 4, lengthof(_name_turkish_suffix), seed)], last); break; default: buf = strecpy(buf, _name_turkish_real[SeedModChance( 4, lengthof(_name_turkish_real), seed)], last); break; } return buf; }
/** * Generates English (Original) town name from given seed. * @param buf output buffer * @param seed town name seed * @param last end of buffer */ static char *MakeEnglishOriginalTownName(char *buf, const char *last, uint32 seed) { char *orig = buf; /* optional first segment */ int i = SeedChanceBias(0, lengthof(_name_original_english_1), seed, 50); if (i >= 0) buf = strecpy(buf, _name_original_english_1[i], last); /* mandatory middle segments */ buf = strecpy(buf, _name_original_english_2[SeedChance(4, lengthof(_name_original_english_2), seed)], last); buf = strecpy(buf, _name_original_english_3[SeedChance(7, lengthof(_name_original_english_3), seed)], last); buf = strecpy(buf, _name_original_english_4[SeedChance(10, lengthof(_name_original_english_4), seed)], last); buf = strecpy(buf, _name_original_english_5[SeedChance(13, lengthof(_name_original_english_5), seed)], last); /* optional last segment */ i = SeedChanceBias(15, lengthof(_name_original_english_6), seed, 60); if (i >= 0) buf = strecpy(buf, _name_original_english_6[i], last); /* Ce, Ci => Ke, Ki */ if (orig[0] == 'C' && (orig[1] == 'e' || orig[1] == 'i')) { orig[0] = 'K'; } assert(buf - orig >= 4); ReplaceEnglishWords(orig, true); return buf; }
/** * A client has requested the names of some NewGRFs. * * Replying this can be tricky as we have a limit of SEND_MTU bytes * in the reply packet and we can send up to 100 bytes per NewGRF * (GRF ID, MD5sum and NETWORK_GRF_NAME_LENGTH bytes for the name). * As SEND_MTU is _much_ less than 100 * NETWORK_MAX_GRF_COUNT, it * could be that a packet overflows. To stop this we only reply * with the first N NewGRFs so that if the first N + 1 NewGRFs * would be sent, the packet overflows. * in_reply and in_reply_count are used to keep a list of GRFs to * send in the reply. */ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_GET_NEWGRFS) { uint8 num_grfs; uint i; const GRFConfig *in_reply[NETWORK_MAX_GRF_COUNT]; uint8 in_reply_count = 0; size_t packet_len = 0; DEBUG(net, 6, "[udp] newgrf data request from %s", client_addr->GetAddressAsString()); num_grfs = p->Recv_uint8 (); if (num_grfs > NETWORK_MAX_GRF_COUNT) return; for (i = 0; i < num_grfs; i++) { GRFConfig c; const GRFConfig *f; this->Recv_GRFIdentifier(p, &c); /* Find the matching GRF file */ f = FindGRFConfig(c.grfid, c.md5sum); if (f == NULL) continue; // The GRF is unknown to this server /* If the reply might exceed the size of the packet, only reply * the current list and do not send the other data. * The name could be an empty string, if so take the filename. */ packet_len += sizeof(c.grfid) + sizeof(c.md5sum) + min(strlen((f->name != NULL && !StrEmpty(f->name)) ? f->name : f->filename) + 1, (size_t)NETWORK_GRF_NAME_LENGTH); if (packet_len > SEND_MTU - 4) { // 4 is 3 byte header + grf count in reply break; } in_reply[in_reply_count] = f; in_reply_count++; } if (in_reply_count == 0) return; Packet packet(PACKET_UDP_SERVER_NEWGRFS); packet.Send_uint8(in_reply_count); for (i = 0; i < in_reply_count; i++) { char name[NETWORK_GRF_NAME_LENGTH]; /* The name could be an empty string, if so take the filename */ strecpy(name, (in_reply[i]->name != NULL && !StrEmpty(in_reply[i]->name)) ? in_reply[i]->name : in_reply[i]->filename, lastof(name)); this->Send_GRFIdentifier(&packet, in_reply[i]); packet.Send_string(name); } this->SendPacket(&packet, client_addr); }
static char* xreadcons(char *prompt, char *def, int secret, char *buf, int nbuf) { char *p; p = readcons(prompt, def, secret); if(p == nil) return nil; strecpy(buf, buf+nbuf, p); memset(p, 0, strlen(p)); free(p); return buf; }
int waitfor(char *msg) { Waitmsg *w; int pid; if((w=wait()) == nil) return -1; strecpy(msg, msg+ERRMAX, w->msg); pid = w->pid; free(w); return pid; }
static void optionsinit(char* s) { char *o; o = strecpy(oargb, oargb+sizeof(oargb), s)+1; if(getenv("bootargs", o, o - oargb) != nil) *(o-1) = ' '; oargblen = strlen(oargb); oargc = tokenize(oargb, oargv, nelem(oargv)-1); oargv[oargc] = nil; }
/** * Generates Hungarian town name from given seed. * @param buf output buffer * @param seed town name seed * @param last end of buffer */ static char *MakeHungarianTownName(char *buf, const char *last, uint32 seed) { if (SeedChance(12, 15, seed) < 3) { return strecpy(buf, _name_hungarian_real[SeedChance(0, lengthof(_name_hungarian_real), seed)], last); } /* optional first segment */ uint i = SeedChance(3, lengthof(_name_hungarian_1) * 3, seed); if (i < lengthof(_name_hungarian_1)) buf = strecpy(buf, _name_hungarian_1[i], last); /* mandatory middle segments */ buf = strecpy(buf, _name_hungarian_2[SeedChance(3, lengthof(_name_hungarian_2), seed)], last); buf = strecpy(buf, _name_hungarian_3[SeedChance(6, lengthof(_name_hungarian_3), seed)], last); /* optional last segment */ i = SeedChance(10, lengthof(_name_hungarian_4) * 3, seed); if (i < lengthof(_name_hungarian_4)) { buf = strecpy(buf, _name_hungarian_4[i], last); } return buf; }
void ServerNetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) { /* Just a fail-safe.. should never happen */ if (!_network_udp_server) { return; } NetworkGameInfo ngi; /* Update some game_info */ ngi.clients_on = _network_game_info.clients_on; ngi.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); ngi.server_lang = _settings_client.network.server_lang; ngi.use_password = !StrEmpty(_settings_client.network.server_password); ngi.clients_max = _settings_client.network.max_clients; ngi.companies_on = (byte)Company::GetNumItems(); ngi.companies_max = _settings_client.network.max_companies; ngi.spectators_on = NetworkSpectatorCount(); ngi.spectators_max = _settings_client.network.max_spectators; ngi.game_date = _date; ngi.map_width = MapSizeX(); ngi.map_height = MapSizeY(); ngi.map_set = _settings_game.game_creation.landscape; ngi.dedicated = _network_dedicated; ngi.grfconfig = _grfconfig; strecpy(ngi.map_name, _network_game_info.map_name, lastof(ngi.map_name)); strecpy(ngi.server_name, _settings_client.network.server_name, lastof(ngi.server_name)); strecpy(ngi.server_revision, _openttd_revision, lastof(ngi.server_revision)); Packet packet(PACKET_UDP_SERVER_RESPONSE); this->SendNetworkGameInfo(&packet, &ngi); /* Let the client know that we are here */ this->SendPacket(&packet, client_addr); DEBUG(net, 2, "[udp] queried from %s", client_addr->GetHostname()); }