project_files/frontlib/ipc/ipcprotocol.c
author alfadur
Sat, 03 Aug 2019 17:10:19 +0300
changeset 15296 07ab4206f2a9
parent 10017 de822cd3df3a
permissions -rw-r--r--
fix condition
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
}