project_files/frontlib/ipc/ipcprotocol.c
author S.D.
Tue, 27 Sep 2022 14:59:03 +0300
changeset 15878 fc3cb23fd26f
parent 10017 de822cd3df3a
permissions -rw-r--r--
Allow to see rooms of incompatible versions in the lobby For the new clients the room version is shown in a separate column. There is also a hack for previous versions clients: the room vesion specifier is prepended to the room names for rooms of incompatible versions, and the server shows 'incompatible version' error if the client tries to join them.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10017
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     1
/*
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     2
 * Hedgewars, a free turn based strategy game
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     3
 * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     4
 *
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     5
 * This program is free software; you can redistribute it and/or
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     6
 * modify it under the terms of the GNU General Public License
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     7
 * as published by the Free Software Foundation; either version 2
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     8
 * of the License, or (at your option) any later version.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
     9
 *
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    10
 * This program is distributed in the hope that it will be useful,
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    13
 * GNU General Public License for more details.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    14
 *
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    15
 * You should have received a copy of the GNU General Public License
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    16
 * along with this program; if not, write to the Free Software
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    18
 */
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    19
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    20
#include "ipcprotocol.h"
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    21
#include "../util/util.h"
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    22
#include "../util/logging.h"
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    23
#include "../md5/md5.h"
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    24
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    25
#include <stdio.h>
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    26
#include <stdbool.h>
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    27
#include <string.h>
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    28
#include <inttypes.h>
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    29
#include <stdlib.h>
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    30
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    31
int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    32
    int result = -1;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    33
    if(!log_badargs_if2(vec==NULL, fmt==NULL)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    34
        // 1 byte size prefix, 255 bytes max message length, 1 0-byte for vsnprintf
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    35
        char msgbuffer[257];
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    36
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    37
        // Format the message, leaving one byte at the start for the length
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    38
        va_list argp;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    39
        va_start(argp, fmt);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    40
        int msgSize = vsnprintf(msgbuffer+1, 256, fmt, argp);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    41
        va_end(argp);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    42
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    43
        if(!log_e_if(msgSize > 255, "Message too long (%u bytes)", (unsigned)msgSize)
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    44
                && !log_e_if(msgSize < 0, "printf error")) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    45
            // Add the length prefix
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    46
            ((uint8_t*)msgbuffer)[0] = msgSize;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    47
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    48
            // Append it to the vector
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    49
            result = flib_vector_append(vec, msgbuffer, msgSize+1);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    50
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    51
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    52
    return result;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    53
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    54
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    55
int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    56
    int result = -1;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    57
    flib_vector *tempvector = flib_vector_create();
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    58
    if(!log_badargs_if2(vec==NULL, map==NULL)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    59
        bool error = false;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    60
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    61
        if(map->mapgen == MAPGEN_NAMED) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    62
            error |= log_e_if(!map->name, "Missing map name")
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    63
                    || flib_ipc_append_message(tempvector, "emap %s", map->name);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    64
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    65
        if(!mappreview) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    66
            error |= log_e_if(!map->theme, "Missing map theme")
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    67
                    || flib_ipc_append_message(tempvector, "etheme %s", map->theme);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    68
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    69
        error |= flib_ipc_append_seed(tempvector, map->seed);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    70
        error |= flib_ipc_append_message(tempvector, "e$template_filter %i", map->templateFilter);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    71
        error |= flib_ipc_append_message(tempvector, "e$mapgen %i", map->mapgen);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    72
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    73
        if(map->mapgen == MAPGEN_MAZE) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    74
            error |= flib_ipc_append_message(tempvector, "e$maze_size %i", map->mazeSize);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    75
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    76
        if(map->mapgen == MAPGEN_DRAWN) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    77
            /*
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    78
             * We have to split the drawn map data into several edraw messages here because
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    79
             * it can be longer than the maximum message size.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    80
             */
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    81
            const char *edraw = "edraw ";
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    82
            int edrawlen = strlen(edraw);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    83
            for(size_t offset=0; offset<map->drawDataSize; offset+=200) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    84
                size_t bytesRemaining = map->drawDataSize-offset;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    85
                int fragmentsize = bytesRemaining < 200 ? bytesRemaining : 200;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    86
                uint8_t messagesize = edrawlen + fragmentsize;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    87
                error |= flib_vector_append(tempvector, &messagesize, 1);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    88
                error |= flib_vector_append(tempvector, edraw, edrawlen);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    89
                error |= flib_vector_append(tempvector, map->drawData+offset, fragmentsize);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    90
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    91
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    92
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    93
        if(!log_e_if(error, "Error generating map config")) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    94
            // Message created, now we can copy everything.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    95
            flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    96
            if(!flib_vector_append(vec, constbuf.data, constbuf.size)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    97
                result = 0;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    98
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
    99
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   100
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   101
    flib_vector_destroy(tempvector);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   102
    return result;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   103
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   104
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   105
int flib_ipc_append_seed(flib_vector *vec, const char *seed) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   106
    if(log_badargs_if2(vec==NULL, seed==NULL)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   107
        return -1;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   108
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   109
    return flib_ipc_append_message(vec, "eseed %s", seed);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   110
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   111
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   112
int flib_ipc_append_script(flib_vector *vec, const char *script) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   113
    int result = -1;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   114
    if(!log_badargs_if2(vec==NULL, script==NULL)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   115
        result = flib_ipc_append_message(vec, "escript %s", script);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   116
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   117
    return result;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   118
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   119
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   120
int flib_ipc_append_style(flib_vector *vec, const char *style) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   121
    int result = -1;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   122
    char *copy = flib_strdupnull(style);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   123
    if(!log_badargs_if(vec==NULL) && copy) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   124
        if(!strcmp("Normal", copy)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   125
            // "Normal" means no gametype script
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   126
            // TODO if an empty script called "Normal" is added to the scripts directory this can be removed
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   127
            result = 0;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   128
        } else {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   129
            size_t len = strlen(copy);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   130
            for(size_t i=0; i<len; i++) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   131
                if(copy[i] == ' ') {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   132
                    copy[i] = '_';
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   133
                }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   134
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   135
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   136
            result = flib_ipc_append_message(vec, "escript %s%s.lua", MULTIPLAYER_SCRIPT_PATH, copy);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   137
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   138
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   139
    free(copy);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   140
    return result;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   141
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   142
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   143
static uint32_t buildModFlags(const flib_scheme *scheme) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   144
    uint32_t result = 0;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   145
    for(int i=0; i<flib_meta.modCount; i++) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   146
        if(scheme->mods[i]) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   147
            int bitmaskIndex = flib_meta.mods[i].bitmaskIndex;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   148
            result |= (UINT32_C(1) << bitmaskIndex);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   149
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   150
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   151
    return result;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   152
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   153
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   154
int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   155
    int result = -1;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   156
    flib_vector *tempvector = flib_vector_create();
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   157
    if(!log_badargs_if2(vec==NULL, scheme==NULL) && tempvector) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   158
        bool error = false;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   159
        error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, buildModFlags(scheme));
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   160
        for(int i=0; i<flib_meta.settingCount; i++) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   161
            if(flib_meta.settings[i].engineCommand) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   162
                int value = scheme->settings[i];
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   163
                if(flib_meta.settings[i].maxMeansInfinity) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   164
                    value = value>=flib_meta.settings[i].max ? 9999 : value;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   165
                }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   166
                if(flib_meta.settings[i].times1000) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   167
                    value *= 1000;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   168
                }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   169
                error |= flib_ipc_append_message(tempvector, "%s %i", flib_meta.settings[i].engineCommand, value);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   170
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   171
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   172
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   173
        if(!error) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   174
            // Message created, now we can copy everything.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   175
            flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   176
            if(!flib_vector_append(vec, constbuf.data, constbuf.size)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   177
                result = 0;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   178
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   179
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   180
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   181
    flib_vector_destroy(tempvector);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   182
    return result;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   183
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   184
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   185
static int appendWeaponSet(flib_vector *vec, flib_weaponset *set) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   186
    return flib_ipc_append_message(vec, "eammloadt %s", set->loadout)
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   187
        || flib_ipc_append_message(vec, "eammprob %s", set->crateprob)
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   188
        || flib_ipc_append_message(vec, "eammdelay %s", set->delay)
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   189
        || flib_ipc_append_message(vec, "eammreinf %s", set->crateammo);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   190
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   191
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   192
static void calculateMd5Hex(const char *in, char out[33]) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   193
    md5_state_t md5state;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   194
    uint8_t md5bytes[16];
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   195
    md5_init(&md5state);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   196
    md5_append(&md5state, (unsigned char*)in, strlen(in));
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   197
    md5_finish(&md5state, md5bytes);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   198
    for(int i=0;i<sizeof(md5bytes); i++) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   199
        snprintf(out+i*2, 3, "%02x", (unsigned)md5bytes[i]);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   200
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   201
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   202
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   203
static int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   204
    int result = -1;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   205
    flib_vector *tempvector = flib_vector_create();
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   206
    if(!log_badargs_if2(vec==NULL, team==NULL) && tempvector) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   207
        bool error = false;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   208
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   209
        if(!perHogAmmo && !noAmmoStore) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   210
            error = error
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   211
                    || appendWeaponSet(tempvector, team->hogs[0].weaponset)
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   212
                    || flib_ipc_append_message(tempvector, "eammstore");
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   213
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   214
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   215
        char md5Hex[33];
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   216
        calculateMd5Hex(team->ownerName ? team->ownerName : "", md5Hex);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   217
        if(team->colorIndex<0 || team->colorIndex>=flib_teamcolor_count) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   218
            flib_log_e("Color index out of bounds for team %s: %i", team->name, team->colorIndex);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   219
            error = true;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   220
        } else {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   221
            error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", md5Hex, flib_teamcolors[team->colorIndex], team->name);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   222
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   223
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   224
        if(team->remoteDriven) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   225
            error |= flib_ipc_append_message(tempvector, "erdriven");
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   226
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   227
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   228
        error |= flib_ipc_append_message(tempvector, "egrave %s", team->grave);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   229
        error |= flib_ipc_append_message(tempvector, "efort %s", team->fort);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   230
        error |= flib_ipc_append_message(tempvector, "evoicepack %s", team->voicepack);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   231
        error |= flib_ipc_append_message(tempvector, "eflag %s", team->flag);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   232
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   233
        for(int i=0; i<team->bindingCount; i++) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   234
            error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   235
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   236
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   237
        for(int i=0; i<team->hogsInGame; i++) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   238
            if(perHogAmmo && !noAmmoStore) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   239
                error |= appendWeaponSet(tempvector, team->hogs[i].weaponset);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   240
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   241
            error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   242
            error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   243
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   244
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   245
        if(!error) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   246
            // Message created, now we can copy everything.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   247
            flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   248
            if(!flib_vector_append(vec, constbuf.data, constbuf.size)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   249
                result = 0;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   250
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   251
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   252
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   253
    flib_vector_destroy(tempvector);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   254
    return result;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   255
}
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   256
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   257
int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   258
    int result = -1;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   259
    flib_vector *tempvector = flib_vector_create();
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   260
    if(!log_badargs_if2(vec==NULL, setup==NULL) && tempvector) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   261
        bool error = false;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   262
        bool perHogAmmo = false;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   263
        bool sharedAmmo = false;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   264
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   265
        error |= flib_ipc_append_message(vec, netgame ? "TN" : "TL");
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   266
        if(setup->map) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   267
            error |= flib_ipc_append_mapconf(tempvector, setup->map, false);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   268
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   269
        if(setup->style) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   270
            error |= flib_ipc_append_style(tempvector, setup->style);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   271
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   272
        if(setup->gamescheme) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   273
            error |= flib_ipc_append_gamescheme(tempvector, setup->gamescheme);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   274
            sharedAmmo = flib_scheme_get_mod(setup->gamescheme, "sharedammo");
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   275
            // Shared ammo has priority over per-hog ammo
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   276
            perHogAmmo = !sharedAmmo && flib_scheme_get_mod(setup->gamescheme, "perhogammo");
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   277
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   278
        if(setup->teamlist->teams && setup->teamlist->teamCount>0) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   279
            int *clanColors = flib_calloc(setup->teamlist->teamCount, sizeof(int));
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   280
            if(!clanColors) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   281
                error = true;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   282
            } else {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   283
                int clanCount = 0;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   284
                for(int i=0; !error && i<setup->teamlist->teamCount; i++) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   285
                    flib_team *team = setup->teamlist->teams[i];
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   286
                    // Find the clan index of this team (clans are identified by color).
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   287
                    bool newClan = false;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   288
                    int clan = 0;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   289
                    while(clan<clanCount && clanColors[clan] != team->colorIndex) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   290
                        clan++;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   291
                    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   292
                    if(clan==clanCount) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   293
                        newClan = true;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   294
                        clanCount++;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   295
                        clanColors[clan] = team->colorIndex;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   296
                    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   297
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   298
                    // If shared ammo is active, only add an ammo store for the first team in each clan.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   299
                    bool noAmmoStore = sharedAmmo&&!newClan;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   300
                    error |= flib_ipc_append_addteam(tempvector, setup->teamlist->teams[i], perHogAmmo, noAmmoStore);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   301
                }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   302
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   303
            free(clanColors);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   304
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   305
        error |= flib_ipc_append_message(tempvector, "!");
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   306
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   307
        if(!error) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   308
            // Message created, now we can copy everything.
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   309
            flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector);
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   310
            if(!flib_vector_append(vec, constbuf.data, constbuf.size)) {
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   311
                result = 0;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   312
            }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   313
        }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   314
    }
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   315
    return result;
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 7497
diff changeset
   316
}