forked from github/server
parent
d530340db6
commit
7302f7cd4c
|
@ -23,6 +23,10 @@
|
|||
#define CONFIG_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define VC_EXTRALEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <Windows.h>
|
||||
# undef MOUSE_MOVED
|
||||
# define STDIO_CP 1252 /* log.c, convert to console character set */
|
||||
# pragma warning (disable: 4201 4214 4514 4115 4711)
|
||||
# pragma warning(disable: 4056)
|
||||
|
@ -226,11 +230,7 @@ extern char * strdup(const char *s);
|
|||
#endif
|
||||
|
||||
#if !defined(MAX_PATH)
|
||||
# ifdef WIN32
|
||||
# define VC_EXTRALEAN
|
||||
# include <Windows.h>
|
||||
# undef MOUSE_MOVED
|
||||
# elif defined(PATH_MAX)
|
||||
# if defined(PATH_MAX)
|
||||
# define MAX_PATH PATH_MAX
|
||||
# else
|
||||
# define MAX_PATH 1024
|
||||
|
@ -242,10 +242,10 @@ extern char * strdup(const char *s);
|
|||
**** ****/
|
||||
#ifndef NOMINMAX
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
# define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -260,9 +260,7 @@ extern char * strdup(const char *s);
|
|||
/**** ****
|
||||
** The Eressea boolean type **
|
||||
**** ****/
|
||||
#if defined(WIN32)
|
||||
typedef unsigned char boolean;
|
||||
#elif defined(BOOLEAN)
|
||||
#if defined(BOOLEAN)
|
||||
# define boolean BOOLEAN
|
||||
#else
|
||||
typedef int boolean; /* not bool! wrong size. */
|
||||
|
|
|
@ -2293,18 +2293,9 @@ strdup(const char *s)
|
|||
#endif
|
||||
|
||||
void
|
||||
remove_empty_factions(boolean writedropouts)
|
||||
remove_empty_factions(void)
|
||||
{
|
||||
faction **fp, *f3;
|
||||
FILE *dofp = NULL;
|
||||
char zText[MAX_PATH];
|
||||
sprintf(zText, "%s/dropouts.%d", basepath(), turn);
|
||||
|
||||
if (writedropouts) dofp = fopen(zText, "w");
|
||||
if (dofp) {
|
||||
const unsigned char utf8_bom[4] = { 0xef, 0xbb, 0xbf };
|
||||
fwrite(utf8_bom, 1, 3, dofp);
|
||||
}
|
||||
|
||||
for (fp = &factions; *fp;) {
|
||||
faction * f = *fp;
|
||||
|
@ -2318,11 +2309,6 @@ remove_empty_factions(boolean writedropouts)
|
|||
|
||||
/* Einfach in eine Datei schreiben und später vermailen */
|
||||
|
||||
if (dofp) {
|
||||
fprintf(dofp, "%3d %s %s %s\n",
|
||||
f->age, LOC(default_locale, rc_name(f->race, 0)), f->email,
|
||||
factionname(f));
|
||||
}
|
||||
if (updatelog) fprintf(updatelog, "dropout %s\n", itoa36(f->no));
|
||||
|
||||
for (f3 = factions; f3; f3 = f3->next) {
|
||||
|
@ -2361,8 +2347,6 @@ remove_empty_factions(boolean writedropouts)
|
|||
}
|
||||
else fp = &(*fp)->next;
|
||||
}
|
||||
|
||||
if (dofp) fclose(dofp);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -130,7 +130,7 @@ typedef struct ally {
|
|||
|
||||
void remove_empty_units_in_region(struct region *r);
|
||||
void remove_empty_units(void);
|
||||
void remove_empty_factions(boolean writedropouts);
|
||||
void remove_empty_factions(void);
|
||||
|
||||
typedef struct strlist {
|
||||
struct strlist *next;
|
||||
|
|
|
@ -1598,7 +1598,7 @@ readgame(const char * filename, int mode, int backup)
|
|||
}
|
||||
}
|
||||
if (loadplane || maxregions>=0) {
|
||||
remove_empty_factions(false);
|
||||
remove_empty_factions();
|
||||
}
|
||||
log_info((1, "Done loading turn %d.\n", turn));
|
||||
return 0;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <kernel/faction.h>
|
||||
#include <util/unicode.h>
|
||||
#include <util/base36.h>
|
||||
#include <util/log.h>
|
||||
#include <sqlite3.h>
|
||||
#include <md5.h>
|
||||
#include <assert.h>
|
||||
|
@ -19,133 +20,212 @@ faction * get_faction_by_id(int uid)
|
|||
}
|
||||
|
||||
#define SQL_EXPECT(res, val) if (res!=val) { return val; }
|
||||
#define MAX_EMAIL_LENGTH 64
|
||||
#define MD5_LENGTH 32
|
||||
#define MD5_LENGTH_0 (MD5_LENGTH+1) /* MD5 + zero-terminator */
|
||||
#define MAX_FACTION_NAME 64
|
||||
#define MAX_FACTION_NAME_0 (MAX_FACTION_NAME+1)
|
||||
typedef struct stmt_cache {
|
||||
sqlite3 * db;
|
||||
sqlite3_stmt * stmt;
|
||||
const char * sql;
|
||||
int inuse;
|
||||
} stmt_cache;
|
||||
|
||||
#define MAX_STMT_CACHE 64
|
||||
static stmt_cache cache[MAX_STMT_CACHE];
|
||||
static int cache_insert;
|
||||
|
||||
static sqlite3_stmt *
|
||||
stmt_cache_get(sqlite3 * db, const char * sql)
|
||||
{
|
||||
int i, res;
|
||||
|
||||
for (i=0;i!=MAX_STMT_CACHE && cache[i].db;++i) {
|
||||
if (cache[i].sql==sql && cache[i].db==db) {
|
||||
cache[i].inuse = 1;
|
||||
res = sqlite3_reset(cache[i].stmt);
|
||||
return cache[i].stmt;
|
||||
}
|
||||
}
|
||||
if (i==MAX_STMT_CACHE) {
|
||||
while (cache[cache_insert].inuse) {
|
||||
cache[cache_insert].inuse = 0;
|
||||
cache_insert = (cache_insert+1)&(MAX_STMT_CACHE-1);
|
||||
}
|
||||
i = cache_insert;
|
||||
res = sqlite3_finalize(cache[i].stmt);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
}
|
||||
cache[i].inuse = 1;
|
||||
cache[i].db = db;
|
||||
cache[i].sql = sql;
|
||||
res = sqlite3_prepare_v2(db, sql, -1, &cache[i].stmt, NULL);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
return cache[i].stmt;
|
||||
}
|
||||
|
||||
|
||||
typedef struct db_faction {
|
||||
sqlite3_uint64 id_faction;
|
||||
sqlite3_uint64 id_email;
|
||||
int no;
|
||||
const char * email;
|
||||
const char * passwd_md5;
|
||||
const char * name;
|
||||
} db_faction;
|
||||
|
||||
static int
|
||||
db_update_email(sqlite3 * db, const faction * f, const db_faction * dbstate, boolean force, /* [OUT] */ sqlite3_uint64 * id_email)
|
||||
{
|
||||
boolean update = force;
|
||||
int res = SQLITE_OK;
|
||||
char email_lc[MAX_EMAIL_LENGTH];
|
||||
|
||||
if (update) {
|
||||
unicode_utf8_tolower(email_lc, sizeof(email_lc), f->email);
|
||||
} else {
|
||||
if (strcmp(dbstate->email, f->email)!=0) {
|
||||
unicode_utf8_tolower(email_lc, sizeof(email_lc), f->email);
|
||||
if (strcmp(dbstate->email, email_lc)!=0) {
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (update) {
|
||||
char email_md5[MD5_LENGTH_0];
|
||||
int i;
|
||||
md5_state_t ms;
|
||||
md5_byte_t digest[16];
|
||||
const char sql_insert_email[] =
|
||||
"INSERT OR FAIL INTO email (email,md5) VALUES (?,?)";
|
||||
const char sql_select_email[] =
|
||||
"SELECT id FROM email WHERE md5=?";
|
||||
sqlite3_stmt *stmt_insert_email = stmt_cache_get(db, sql_insert_email);
|
||||
sqlite3_stmt *stmt_select_email = stmt_cache_get(db, sql_select_email);
|
||||
|
||||
md5_init(&ms);
|
||||
md5_append(&ms, (md5_byte_t*)email_lc, (int)strlen(email_lc));
|
||||
md5_finish(&ms, digest);
|
||||
for (i=0;i!=16;++i) sprintf(email_md5+2*i, "%.02x", digest[i]);
|
||||
|
||||
res = sqlite3_bind_text(stmt_insert_email, 1, email_lc, -1, SQLITE_TRANSIENT);
|
||||
res = sqlite3_bind_text(stmt_insert_email, 2, email_md5, MD5_LENGTH, SQLITE_TRANSIENT);
|
||||
res = sqlite3_step(stmt_insert_email);
|
||||
|
||||
if (res==SQLITE_DONE) {
|
||||
*id_email = sqlite3_last_insert_rowid(db);
|
||||
} else {
|
||||
res = sqlite3_bind_text(stmt_select_email, 1, email_md5, MD5_LENGTH, SQLITE_TRANSIENT);
|
||||
res = sqlite3_step(stmt_select_email);
|
||||
SQL_EXPECT(res, SQLITE_ROW);
|
||||
*id_email = sqlite3_column_int64(stmt_select_email, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int
|
||||
db_update_factions(sqlite3 * db)
|
||||
db_update_factions(sqlite3 * db, boolean force)
|
||||
{
|
||||
int game_id = 6;
|
||||
// const char * sql = "INSERT OR REPLACE INTO email (md5, email) VALUES(?, ?)";
|
||||
const char sql_select[] =
|
||||
"SELECT faction.id, faction.email_id, faction.code, email.email FROM email, faction"
|
||||
" WHERE email.id=faction.email_id AND faction.game_id=?";
|
||||
const char sql_insert_email[] =
|
||||
"INSERT OR FAIL INTO email (email,md5) VALUES (?,?)";
|
||||
const char sql_select_email[] =
|
||||
"SELECT id FROM email WHERE md5=?";
|
||||
const char sql_update_faction[] =
|
||||
"UPDATE faction SET email_id=?, lastturn=?, code=?, name=? WHERE id=?";
|
||||
|
||||
"SELECT faction.id, faction.email_id, faction.code, email.email, faction.password_md5, faction.name, faction.lastturn FROM email, faction"
|
||||
" WHERE email.id=faction.email_id AND faction.game_id=? AND (lastturn IS NULL OR lastturn>?)";
|
||||
sqlite3_stmt *stmt_select = stmt_cache_get(db, sql_select);
|
||||
faction * f;
|
||||
sqlite3_stmt *stmt_insert_email;
|
||||
sqlite3_stmt *stmt_select_email;
|
||||
sqlite3_stmt *stmt_update_faction;
|
||||
sqlite3_stmt *stmt_select;
|
||||
int res;
|
||||
|
||||
res = sqlite3_prepare_v2(db, sql_select_email, (int)sizeof(sql_select_email), &stmt_select_email, NULL);
|
||||
if (res!=SQLITE_OK) return res;
|
||||
res = sqlite3_prepare_v2(db, sql_insert_email, (int)sizeof(sql_insert_email), &stmt_insert_email, NULL);
|
||||
if (res!=SQLITE_OK) return res;
|
||||
res = sqlite3_prepare_v2(db, sql_select, (int)sizeof(sql_select), &stmt_select, NULL);
|
||||
if (res!=SQLITE_OK) return res;
|
||||
res = sqlite3_prepare_v2(db, sql_update_faction, sizeof(sql_update_faction), &stmt_update_faction, NULL);
|
||||
if (res!=SQLITE_OK) return res;
|
||||
|
||||
res = sqlite3_bind_int(stmt_select, 1, game_id);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_int(stmt_select, 2, turn-2);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
for (;;) {
|
||||
sqlite3_uint64 idfaction, idemail;
|
||||
char email[64];
|
||||
int length, no;
|
||||
sqlite3_uint64 id_faction;
|
||||
int lastturn;
|
||||
|
||||
res = sqlite3_step(stmt_select);
|
||||
if (res!=SQLITE_ROW) break;
|
||||
idfaction = sqlite3_column_int64(stmt_select, 0);
|
||||
idemail = sqlite3_column_int64(stmt_select, 1);
|
||||
no = sqlite3_column_int(stmt_select, 2);
|
||||
length = sqlite3_column_bytes(stmt_select, 3);
|
||||
assert(length<sizeof(email));
|
||||
memcpy(email, sqlite3_column_text(stmt_select, 3), length);
|
||||
email[length] = 0;
|
||||
f = get_faction_by_id((int)idfaction);
|
||||
if (f==NULL) {
|
||||
// update status?
|
||||
} else {
|
||||
const char * code = itoa36(f->no);
|
||||
if (strcmp(f->email, email)!=0) {
|
||||
char lower[64];
|
||||
unicode_utf8_tolower(lower, sizeof(lower), f->email);
|
||||
if (strcmp(email, lower)!=0) {
|
||||
char md5hash[33];
|
||||
md5_state_t ms;
|
||||
md5_byte_t digest[16];
|
||||
int i;
|
||||
|
||||
md5_init(&ms);
|
||||
md5_append(&ms, (md5_byte_t*)lower, (int)strlen(lower));
|
||||
md5_finish(&ms, digest);
|
||||
for (i=0;i!=16;++i) sprintf(md5hash+2*i, "%.02x", digest[i]);
|
||||
id_faction = sqlite3_column_int64(stmt_select, 0);
|
||||
lastturn = sqlite3_column_int(stmt_select, 6);
|
||||
f = get_faction_by_id((int)id_faction);
|
||||
|
||||
idemail = 0;
|
||||
res = sqlite3_bind_text(stmt_insert_email, 1, lower, -1, SQLITE_TRANSIENT);
|
||||
res = sqlite3_bind_text(stmt_insert_email, 2, md5hash, -1, SQLITE_TRANSIENT);
|
||||
res = sqlite3_step(stmt_insert_email);
|
||||
if (res==SQLITE_DONE) {
|
||||
idemail = sqlite3_last_insert_rowid(db);
|
||||
} else {
|
||||
res = sqlite3_bind_text(stmt_select_email, 1, md5hash, -1, SQLITE_TRANSIENT);
|
||||
res = sqlite3_step(stmt_select_email);
|
||||
if (res==SQLITE_ROW) {
|
||||
idemail = sqlite3_column_int64(stmt_select_email, 0);
|
||||
}
|
||||
res = sqlite3_reset(stmt_select_email);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
}
|
||||
res = sqlite3_reset(stmt_insert_email);
|
||||
}
|
||||
if (f==NULL || !f->alive) {
|
||||
if (lastturn==0) {
|
||||
const char sql_update[] = "UPDATE faction SET lastturn=? WHERE id=?";
|
||||
sqlite3_stmt *stmt = stmt_cache_get(db, sql_update);
|
||||
|
||||
lastturn = f?f->lastorders:turn-1;
|
||||
sqlite3_bind_int(stmt, 1, lastturn);
|
||||
sqlite3_bind_int64(stmt, 2, id_faction);
|
||||
res = sqlite3_step(stmt);
|
||||
SQL_EXPECT(res, SQLITE_DONE);
|
||||
}
|
||||
res = sqlite3_bind_int64(stmt_update_faction, 1, idemail);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_int(stmt_update_faction, 2, f->lastorders);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_text(stmt_update_faction, 3, code, -1, SQLITE_TRANSIENT);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_text(stmt_update_faction, 4, f->name, -1, SQLITE_TRANSIENT);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_int64(stmt_update_faction, 5, idfaction);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_step(stmt_update_faction);
|
||||
SQL_EXPECT(res, SQLITE_DONE);
|
||||
res = sqlite3_reset(stmt_update_faction);
|
||||
} else {
|
||||
md5_state_t ms;
|
||||
md5_byte_t digest[16];
|
||||
int i;
|
||||
char passwd_md5[MD5_LENGTH_0];
|
||||
sqlite3_uint64 id_email;
|
||||
boolean update = force;
|
||||
db_faction dbstate;
|
||||
const char * no_b36;
|
||||
|
||||
fset(f, FFL_MARK);
|
||||
dbstate.id_faction = id_faction;
|
||||
dbstate.id_email = sqlite3_column_int64(stmt_select, 1);
|
||||
no_b36 = (const char *)sqlite3_column_text(stmt_select, 2);
|
||||
dbstate.no = no_b36?atoi36(no_b36):-1;
|
||||
dbstate.email = (const char *)sqlite3_column_text(stmt_select, 3);
|
||||
dbstate.passwd_md5 = (const char *)sqlite3_column_text(stmt_select, 4);
|
||||
dbstate.name = (const char *)sqlite3_column_text(stmt_select, 5);
|
||||
|
||||
id_email = dbstate.id_email;
|
||||
res = db_update_email(db, f, &dbstate, force, &id_email);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
|
||||
md5_init(&ms);
|
||||
md5_append(&ms, (md5_byte_t*)f->passw, (int)strlen(f->passw));
|
||||
md5_finish(&ms, digest);
|
||||
for (i=0;i!=16;++i) sprintf(passwd_md5+2*i, "%.02x", digest[i]);
|
||||
|
||||
if (!update) {
|
||||
update = ((id_email!=0 && dbstate.id_email!=id_email) || dbstate.no!=f->no
|
||||
|| dbstate.passwd_md5==NULL || strcmp(passwd_md5, dbstate.passwd_md5)!=0
|
||||
|| dbstate.name==NULL || strncmp(f->name, dbstate.name, MAX_FACTION_NAME)!=0);
|
||||
}
|
||||
if (update) {
|
||||
const char sql_update_faction[] =
|
||||
"UPDATE faction SET email_id=?, password_md5=?, code=?, name=?, firstturn=? WHERE id=?";
|
||||
sqlite3_stmt *stmt_update_faction = stmt_cache_get(db, sql_update_faction);
|
||||
|
||||
res = sqlite3_bind_int64(stmt_update_faction, 1, id_email);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_text(stmt_update_faction, 2, passwd_md5, MD5_LENGTH, SQLITE_TRANSIENT);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_text(stmt_update_faction, 3, no_b36, -1, SQLITE_TRANSIENT);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_text(stmt_update_faction, 4, f->name, -1, SQLITE_TRANSIENT);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_int(stmt_update_faction, 5, turn-f->age);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_bind_int64(stmt_update_faction, 6, f->subscription);
|
||||
SQL_EXPECT(res, SQLITE_OK);
|
||||
res = sqlite3_step(stmt_update_faction);
|
||||
SQL_EXPECT(res, SQLITE_DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(stmt_select);
|
||||
/*
|
||||
|
||||
for (f=factions;f;f=f->next) {
|
||||
char email[64];
|
||||
char hash[33];
|
||||
md5_state_t ms;
|
||||
md5_byte_t digest[16];
|
||||
int i;
|
||||
sqlite3_int64 rowid;
|
||||
|
||||
unicode_utf8_tolower(email, sizeof(email), f->email);
|
||||
|
||||
md5_init(&ms);
|
||||
md5_append(&ms, (md5_byte_t*)email, strlen(email));
|
||||
md5_finish(&ms, digest);
|
||||
for (i=0;i!=16;++i) sprintf(hash+2*i, "%.02x", digest[i]);
|
||||
|
||||
res = sqlite3_bind_text(stmt, 1, hash, -1, SQLITE_TRANSIENT);
|
||||
res = sqlite3_bind_text(stmt, 2, email, -1, SQLITE_TRANSIENT);
|
||||
do {
|
||||
res = sqlite3_step(stmt);
|
||||
} while (res!=SQLITE_DONE);
|
||||
rowid = sqlite3_last_insert_rowid(db);
|
||||
// TODO: use rowid to update faction
|
||||
sqlite3_reset(stmt);
|
||||
if (!fval(f, FFL_MARK)) {
|
||||
log_error(("%s (sub=%d, email=%s) has no entry in the database\n", factionname(f), f->subscription, f->email));
|
||||
} else {
|
||||
freset(f, FFL_MARK);
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
*/
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..;../common"
|
||||
AdditionalIncludeDirectories="..;../common;../external"
|
||||
PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
|
|
|
@ -21,12 +21,12 @@ without prior permission by the authors of Eressea.
|
|||
|
||||
#define LTYPE_DB TOLUA_CAST "db"
|
||||
|
||||
extern int db_update_factions(sqlite3 * db);
|
||||
extern int db_update_factions(sqlite3 * db, boolean force);
|
||||
static int
|
||||
tolua_db_update_factions(lua_State* L)
|
||||
{
|
||||
sqlite3 * db = (sqlite3 *)tolua_tousertype(L, 1, 0);
|
||||
db_update_factions(db);
|
||||
db_update_factions(db, tolua_toboolean(L, 2, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -623,7 +623,7 @@ tolua_write_game(lua_State* L)
|
|||
|
||||
int result, m = IO_BINARY;
|
||||
if (mode && strcmp(mode, "text")==0) m = IO_TEXT;
|
||||
remove_empty_factions(true);
|
||||
remove_empty_factions();
|
||||
result = writegame(filename, m);
|
||||
|
||||
tolua_pushnumber(L, (lua_Number)result);
|
||||
|
|
Loading…
Reference in New Issue