96 if (sl->
len+size >
sizeof(sl->
buf)) {
108 sl->
buf[sl->
len++] = data;
118 sl->
buf[sl->
len++] = (data>>8)&0xff;
119 sl->
buf[sl->
len++] = data&0xff;
129 sl->
buf[sl->
len++] = (data>>24)&0xff;
130 sl->
buf[sl->
len++] = (data>>16)&0xff;
131 sl->
buf[sl->
len++] = (data>>8)&0xff;
132 sl->
buf[sl->
len++] = data&0xff;
142 sl->
buf[sl->
len++] = (char)((data>>56)&0xff);
143 sl->
buf[sl->
len++] = (char)((data>>48)&0xff);
144 sl->
buf[sl->
len++] = (char)((data>>40)&0xff);
145 sl->
buf[sl->
len++] = (char)((data>>32)&0xff);
146 sl->
buf[sl->
len++] = (char)((data>>24)&0xff);
147 sl->
buf[sl->
len++] = (char)((data>>16)&0xff);
148 sl->
buf[sl->
len++] = (char)((data>>8)&0xff);
149 sl->
buf[sl->
len++] = (char)(data&0xff);
169 memcpy(sl->
buf+sl->
len, data, len);
192 assert(len <= 65535);
207 size =
sizeof(sl->
buf)-sl->
len;
209 va_start(arg, format);
210 n = vsnprintf((
char *)sl->
buf+sl->
len, size, format, arg);
213 if (n <= -1 || (
size_t)n >= size) {
214 LOG(
llevError,
"Truncating message exceeding MAXSOCKBUF. The message was:\n%s\n", sl->
buf+sl->
len);
216 sl->
len += (size_t)n;
247 return sizeof(sl->
buf)-sl->
len;
255 return ((data[0]<<24)+(data[1]<<16)+(data[2]<<8)+data[3]);
259 return ((data[0]<<8)+data[1]);
282 stat = recv(fd, reinterpret_cast<char *>(sl->
buf+sl->
len), 2-sl->
len, 0);
286 stat = read(fd, sl->
buf+sl->
len, 2-sl->
len);
287 }
while ((stat == -1) && (errno == EINTR));
294 if ((stat == -1) && WSAGetLastError() != WSAEWOULDBLOCK) {
295 if (WSAGetLastError() == WSAECONNRESET)
298 LOG(
llevDebug,
"ReadPacket got error %d, returning -1\n", WSAGetLastError());
303 if (errno == ECONNRESET) {
304 LOG(
llevDebug,
"ReadPacket got error %s, returning -1\n", strerror(errno));
307 if (errno != EAGAIN && errno != EWOULDBLOCK) {
308 LOG(
llevDebug,
"ReadPacket got error %s, returning 0\n", strerror(errno));
326 toread = 2+(sl->
buf[0]<<8)+sl->
buf[1]-sl->
len;
327 if ((toread+(
int)sl->
len) >= len) {
328 LOG(
llevError,
"SockList_ReadPacket: Want to read more bytes than will fit in buffer (%lu>=%lu).\n", (
unsigned long)toread+sl->
len, (
unsigned long)len);
334 stat = recv(fd, reinterpret_cast<char *>(sl->
buf+2), 100, 0);
336 stat = read(fd, sl->
buf+2, 100);
345 stat = recv(fd, reinterpret_cast<char *>(sl->
buf+sl->
len), toread, 0);
348 stat = read(fd, sl->
buf+sl->
len, toread);
349 }
while ((stat < 0) && (errno == EINTR));
353 if ((stat == -1) && WSAGetLastError() != WSAEWOULDBLOCK) {
354 if (WSAGetLastError() == WSAECONNRESET)
357 LOG(
llevDebug,
"ReadPacket got error %d, returning -1\n", WSAGetLastError());
362 if (errno != EAGAIN && errno != EWOULDBLOCK) {
363 LOG(
llevDebug,
"ReadPacket got error %s, returning 0\n", strerror(errno));
379 LOG(
llevError,
"SockList_ReadPacket: Read more bytes than desired.\n");
382 }
while (toread > 0);
401 LOG(
llevDebug,
"Write_To_Socket called with dead socket\n");
406 const int amt = send(ns->
fd, reinterpret_cast<const char *>(buf), len, 0);
408 const int amt = send(ns->
fd, buf, len, 0);
412 if (amt == -1 && WSAGetLastError() != WSAEWOULDBLOCK) {
413 LOG(
llevInfo,
"socket write failed: error code %d, disconnecting client\n",
416 if (errno != EWOULDBLOCK) {
417 LOG(
llevInfo,
"socket write failed: %s, disconnecting client\n",
424 "Write_To_Socket: write would block; disconnecting. Try " 425 "increasing SOCKETBUFSIZE.\n");
429 }
else if (amt != len) {
430 LOG(
llevError,
"Write_To_Socket: write wrote less than requested; " 431 "disconnecting. Try increasing SOCKETBUFSIZE.\n");
451 sl->
buf[0] = ((sl->
len-2)>>8)&0xFF;
452 sl->
buf[1] = (sl->
len-2)&0xFF;
464 static int count_all_players() {
481 #define STAT(name, fmt, val) fprintf(f, "%s %" fmt "\n", name, val); 487 time_t now = time(NULL);
489 int players_total = count_all_players();
492 LOG(
llevInfo,
"STAT: players: %d active, %d total\n", players_active, players_total);
493 LOG(
llevInfo,
"CSSTAT: %.16s tot %d %d %d %ld inc %d %d %d %ld\n",
508 STAT(
"players_total",
"d", players_total);
509 STAT(
"players_active",
"d", players_active);
510 STAT(
"ticks_overtime_percent",
"f", ticks_over * 100);
512 STAT(
"ticktime_avg",
"f", avg / 1e3);
513 STAT(
"bytes_in_total",
"d", cst_tot.
ibytes);
514 STAT(
"bytes_out_total",
"d", cst_tot.
obytes);
516 int maps_in_memory = 0;
517 int maps_swapped = 0;
519 switch (
m->in_memory) {
528 STAT(
"maps_in_memory",
"d", maps_in_memory);
531 STAT(
"maps_swapped",
"d", maps_swapped);
short GetShort_String(const unsigned char *data)
void SockList_AddData(SockList *sl, const void *data, size_t len)
Adds a data block.
void SockList_Term(SockList *sl)
Frees all resources allocated by a SockList instance.
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
size_t SockList_Avail(const SockList *sl)
Returns the available bytes in a SockList instance.
int GetInt_String(const unsigned char *data)
Basically does the reverse of SockList_AddInt, but on strings instead.
static void Write_To_Socket(socket_struct *ns, const unsigned char *buf, const int len)
This writes data to the socket.
unsigned char buf[MAXSOCKBUF]
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
std::vector< archetype * > players
int nroffreeobjects
How many OBs allocated and free (free)
unsigned long max_ticktime
Defines various flags that both the new client and new server use.
void SockList_NullTerminate(SockList *sl)
Adds a NUL byte without changing the length.
player * first_player
First player.
Socket structure, represents a client-server connection.
void Send_With_Handling(socket_struct *ns, SockList *sl)
Calls Write_To_Socket to send data to the client.
void SockList_ResetRead(SockList *sl)
Resets the length of the stored data for reading.
Global type definitions and header inclusions.
int SockList_ReadPacket(int fd, SockList *sl, int len)
This reads from fd and puts the data in sl.
void SockList_AddLen8Data(SockList *sl, const void *data, size_t len)
Adds a data block prepended with an 8 bit length field.
void SockList_AddInt64(SockList *sl, uint64_t data)
Adds a 64 bit value.
#define MAP_IN_MEMORY
Map is fully loaded.
player * next
Pointer to next player, NULL if this is last.
unsigned long ticks_overtime
Socket_Info socket_info
Socket information.
FILE * of_open(OutputFile *of, const char *fname)
Opens an output file.
#define MAP_SWAPPED
Map spaces have been saved to disk.
short max_conn
Maximum connections received.
int ibytes
ibytes, obytes are bytes in, out.
void SockList_AddPrintf(SockList *sl, const char *format,...)
Adds a printf like formatted string.
void SockList_Reset(SockList *sl)
Resets the length of the stored data for writing.
mapstruct * first_map
First map.
struct Settings settings
Global settings.
void SockList_AddLen16Data(SockList *sl, const void *data, size_t len)
Adds a data block prepended with an 16 bit length field.
unsigned long total_ticktime
void SockList_AddInt(SockList *sl, uint32_t data)
Adds a 32 bit value.
void reset_stats(struct CS_Stats *stats)
int allocated_sockets
Number of allocated items in init_sockets.
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
void SockList_AddString(SockList *sl, const char *data)
Adds a string without length.
void SockList_AddStringBuffer(SockList *sl, StringBuffer *sb)
Deallocates string buffer instance and appends its contents.
int object_count_active(void)
Objects statistics.
static event_registration m
int nrofallocobjects
How many OBs allocated (free + used)
void SockList_AddChar(SockList *sl, unsigned char data)
Adds an 8 bit value.
void write_cs_stats(void)
Only for debugging purposes.
Statistics for the last CS_LOGTIME seconds on the server.
int of_close(OutputFile *of)
Closes an output file.
Functions for creating text output files.
void SockList_Init(SockList *sl)
Initializes the SockList instance.
void SockList_AddShort(SockList *sl, uint16_t data)
Adds a 16 bit value.
static void SockList_Ensure(const SockList *sl, size_t size)
Checks that at least a given number of bytes is available in a SockList instance. ...
A buffer that will be expanded as content is added to it.
Contains the base information we use to make up a packet we want to send.