示例#1
0
/*
	CF_BuildQuota

	Calculates the currently used space
*/
static void
CF_BuildQuota (void)
{
	static dstring_t *path;
	struct dirent *i;
	DIR *dir;

	if (!path)
		path = dstring_new ();
	dsprintf (path, "%s/%s/%s", qfs_userpath, qfs_gamedir->dir.def, CF_DIR);

	dir = opendir (path->str);
	if (!dir)
		return;

	cf_cursize = 0;

	while ((i = readdir (dir))) {
		cf_cursize += CF_GetFileSize (va ("%s/%s", path->str, i->d_name));
	}
	closedir (dir);
}
示例#2
0
static void
SV_Fraglogfile_f (void)
{
	dstring_t  *name;

	if (sv_fraglogfile) {
		SV_Printf ("Frag file logging off.\n");
		Qclose (sv_fraglogfile);
		sv_fraglogfile = NULL;
		return;
	}
	name = dstring_new ();
	if (!QFS_NextFilename (name,
						   va ("%s/frag_", qfs_gamedir->dir.def), ".log")) {
		SV_Printf ("Can't open any logfiles.\n");
		sv_fraglogfile = NULL;
	} else {
		SV_Printf ("Logging frags to %s.\n", name->str);
		sv_fraglogfile = QFS_WOpen (name->str, 0);
	}
	dstring_delete (name);
}
示例#3
0
static void
SV_Snap (int uid)
{
	client_t   *cl;
	int         i;

	for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
		if (cl->state < cs_zombie)
			continue;
		if (cl->userid == uid)
			break;
	}
	if (i >= MAX_CLIENTS) {
		SV_Printf ("userid not found\n");
		return;
	}

	if (!cl->uploadfn)
		cl->uploadfn = dstring_new ();

	if (!QFS_NextFilename (cl->uploadfn,
						   va ("%s/snap/%d-", qfs_gamedir->dir.def, uid),
						   ".pcx")) {
		SV_Printf ("Snap: Couldn't create a file, clean some out.\n");
		dstring_delete (cl->uploadfn);
		cl->uploadfn = 0;
		return;
	}

	memcpy (&cl->snap_from, &net_from, sizeof (net_from));
	if (sv_redirected != RD_NONE)
		cl->remote_snap = true;
	else
		cl->remote_snap = false;

	MSG_ReliableWrite_Begin (&cl->backbuf, svc_stufftext, 24);
	MSG_ReliableWrite_String (&cl->backbuf, "cmd snap\n");
	SV_Printf ("Requesting snap from user %d...\n", uid);
}
示例#4
0
/*
 * Retrieve artefact for the given id.
 */
void get_artefact_by_id (db_t *database, int artefactID,
       struct Artefact *artefact)
{
  dstring_t *ds;
  db_result_t *result;

  ds = dstring_new("SELECT * FROM " DB_TABLE_ARTEFACT
           " WHERE artefactID = %d", artefactID);
  result = db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "get_artefact_by_id: %s", dstring_str(ds));

  /* Bedingung: Artefakt muss vorhanden sein */
  if (db_result_num_rows(result) != 1)
    throw(SQL_EXCEPTION, "get_artefact_by_id: no such artefactID");

  db_result_next_row(result);

  artefact->artefactID      = artefactID;
  artefact->artefactClassID = db_result_get_int(result, "artefactClassID");
  artefact->caveID          = db_result_get_int(result, "caveID");
  artefact->initiated       = db_result_get_int(result, "initiated");
}
示例#5
0
dstring_t *dstring_new_from_http(const char *url)
{
    dstring_t *string = NULL;

    uhttp_t *uhttp = uhttp_init();
    if(uhttp_open_url(uhttp, url) == 0)
    {
        string = dstring_new(NULL);

        uhttp_get(uhttp);
        int rc = uhttp_read_response_headers(uhttp);
        if(rc == 200)
        {
            for(;;)
            {
                rc = uhttp_read_response_cb(uhttp, read_callback, string);
                if(rc == 0)
                    break;
                else if(rc == -1)
                {
                    dstring_free(string, 1);
                    string = NULL;
                    break;
                }
            }
        }
        else
        {
            dstring_free(string, 1);
            string = NULL;
        }
    }

    uhttp_cleanup(uhttp);

    return string;
}
示例#6
0
/*
	NET_StringToAdr

	idnewt
	idnewt:28000
	192.246.40.70
	192.246.40.70:28000
*/
qboolean
NET_StringToAdr (const char *s, netadr_t *a)
{
	static dstring_t *copy;
	char       *colon;
	struct hostent *h;
	AF_address_t sadr;

	if (!copy)
		copy = dstring_new ();

	memset (&sadr, 0, sizeof (sadr));
	sadr.s4.sin_family = AF_INET;

	sadr.s4.sin_port = 0;

	dstring_copystr (copy, s);
	// strip off a trailing :port if present
	for (colon = copy->str; *colon; colon++)
		if (*colon == ':') {
			*colon = 0;
			sadr.s4.sin_port = htons ((unsigned short) atoi (colon + 1));
		}

	if (copy->str[0] >= '0' && copy->str[0] <= '9') {
		int         addr = inet_addr (copy->str);
		memcpy (&sadr.s4.sin_addr, &addr, ADDR_SIZE);
	} else {
		if (!(h = gethostbyname (copy->str)))
			return 0;
		memcpy (&sadr.s4.sin_addr, h->h_addr_list[0], ADDR_SIZE);
	}

	SockadrToNetadr (&sadr, a);

	return true;
}
示例#7
0
static void takeover_cave(db_t *database,
		   int    cave_id,
		   int    attacker_id,
		   const char   *return_start)
{
  /* change owner of cave */
  db_query(database, "UPDATE " DB_TABLE_CAVE " SET playerID = %d"
		     " WHERE caveID = %d", attacker_id, cave_id);

  dstring_t *ds;
  ds = dstring_new("UPDATE Event_movement SET target_caveID = source_caveID, ");
  dstring_append(ds, "end = addtime('%s',timediff('%s',start)), ",return_start,return_start);
  dstring_append(ds, "start='%s', ",return_start);
  dstring_append(ds, "movementID = 5 where caveID = %d and caveID = source_caveID",cave_id);
  debug(DEBUG_SQL, "Torben %s", dstring_str(ds));
  db_query_dstring(database, ds);


  /* delete research from event table*/
  db_query(database, "DELETE FROM Event_science WHERE caveID = %d", cave_id);

  /* copy sciences from new owner to cave */
  science_update_caves(database, attacker_id);
}
示例#8
0
static void
qtv_print (const char *fmt, va_list args)
{
	static int pending;
	static dstring_t *msg;

	if (!msg)
		msg = dstring_new ();

	dvsprintf (msg, fmt, args);
	if (qtv_redirected)
		dstring_appendstr (&outputbuf, msg->str);
	else {
		time_t      mytime;
		struct tm  *local;
		char        stamp[123];

		if (pending) {
			Con_Printf ("%s", msg->str);
		} else {
			mytime = time (NULL);
			local = localtime (&mytime);
#ifdef _WIN32
			strftime (stamp, sizeof (stamp), "[%b %d %X] ", local);
#else
			strftime (stamp, sizeof (stamp), "[%b %e %X] ", local);
#endif
			Con_Printf ("%s%s", stamp, msg->str);
		}
		if (msg->str[0] && msg->str[strlen (msg->str) - 1] != '\n') {
			pending = 1;
		} else {
			pending = 0;
		}
	}
}
示例#9
0
/*
	CL_SendConnectPacket

	called by CL_Connect_f and CL_CheckResend
*/
static void
CL_SendConnectPacket (void)
{
	dstring_t  *data;
	double      t1, t2;

// JACK: Fixed bug where DNS lookups would cause two connects real fast
//		 Now, adds lookup time to the connect time.
//		 Should I add it to realtime instead?!?!

	if (cls.state != ca_disconnected)
		return;

	t1 = Sys_DoubleTime ();

	if (!NET_StringToAdr (cls.servername->str, &cls.server_addr)) {
		Sys_Printf ("Bad server address\n");
		connect_time = -1;
		return;
	}

	if (cls.server_addr.port == 0)
		cls.server_addr.port = BigShort (27500);
	t2 = Sys_DoubleTime ();

	connect_time = realtime + t2 - t1;	// for retransmit requests

	cls.qport = qport->int_val;

	data = dstring_new ();
	dsprintf (data, "%c%c%c%cconnect %i %i %i \"%s\"\n",
			  255, 255, 255, 255, PROTOCOL_VERSION, cls.qport, cls.challenge,
			  Info_MakeString (cls.userinfo, 0));
	Netchan_SendPacket (strlen (data->str), data->str, cls.server_addr);
	dstring_delete (data);
}
示例#10
0
VISIBLE tex_t *
LoadImage (const char *imageFile)
{
	int         tmp;
	dstring_t  *tmpFile;
	char       *ext;
	tex_t      *tex = NULL;
	QFile      *fp;

	// Get the file name without extension
	tmpFile = dstring_new ();
	dstring_copystr (tmpFile, imageFile);
	ext = strrchr (tmpFile->str, '.');
	if (ext)
		tmp = ext - tmpFile->str;
	else
		tmp = tmpFile->size - 1;

	// Check for a .png
	dstring_replace (tmpFile, tmp, tmpFile->size, ".png", 5);
	QFS_FOpenFile (tmpFile->str, &fp);
	if (fp) {
		tex = LoadPNG (fp);
		Qclose (fp);
		dstring_delete (tmpFile);
		return (tex);
	}

	// Check for a .tga
	dstring_replace (tmpFile, tmp, tmpFile->size, ".tga", 5);
	QFS_FOpenFile (tmpFile->str, &fp);
	if (fp) {
		tex = LoadTGA (fp);
		Qclose (fp);
		dstring_delete (tmpFile);
		return (tex);
	}

/*
	// Check for a .jpg
	dstring_replace (tmpFile, tmp, tmpFile->size, ".jpg", 5);
	QFS_FOpenFile (tmpFile->str, &fp);
	if (fp) {
		tex = LoadJPG (fp);
		Qclose (fp);
		dstring_delete (tmpFile);
		return (tex);
	}
*/

	// Check for a .pcx
	dstring_replace (tmpFile, tmp, tmpFile->size, ".pcx", 5);
	QFS_FOpenFile (tmpFile->str, &fp);
	if (fp) {
		tex = LoadPCX (fp, 1, NULL); // Convert, some users don't grok paletted
		Qclose (fp);
		dstring_delete (tmpFile);
		return (tex);
	}

	dstring_delete (tmpFile);
	return (tex);
}
示例#11
0
/*
 * merge_artefacts_special
 * Throws exception if needed conditions are not as they should have been.
 */
int merge_artefacts_special (db_t *database,
           const struct Artefact *key_artefact,
           struct Artefact *lock_artefact,
           struct Artefact *result_artefact)
{
  db_result_t *result;
  db_result_t *temp_result;
  int row;
  dstring_t *ds;

  /* get merging formulas */
  ds = dstring_new("SELECT * FROM Artefact_merge_special "
            "WHERE keyID = %d", key_artefact->artefactID);
  result = db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "merge_artefact_special: %s", dstring_str(ds));

  /* check for a suitable merging formula */
  while ((row = db_result_next_row(result)))
  {
    /* some special cases:
     *
     * lockID == 0 || keyID == lockID
     * no lock artefact needed; key artefact transforms directly
     *
     * resultID == 0
     * key and lock artefacts just vanish
     */

    /* lock artefact */
    lock_artefact->artefactID = db_result_get_int(result, "lockID");

    /* special cases: lockID == 0 || keyID == lockID (no lock required) */
    if (lock_artefact->artefactID == 0 ||
  lock_artefact->artefactID == key_artefact->artefactID)
      break;

    /* get lock_artefact */
    /* throws exception, if that artefact is missing */
    get_artefact_by_id(database, lock_artefact->artefactID, lock_artefact);

    /* check: key and lock have to be in the same cave and initiated */
    if (lock_artefact->caveID == key_artefact->caveID &&
  lock_artefact->initiated == ARTEFACT_INITIATED)
      break;
  }

  if (row)
  {
    /* result artefact */
    result_artefact->artefactID = db_result_get_int(result, "resultID");

    /* special case: resultID == 0 */
    if (result_artefact->artefactID != 0)
    {
      /* get result_artefact */
      /* throws exception, if that artefact is missing */
      get_artefact_by_id(database, result_artefact->artefactID, result_artefact);

      /* check: result_artefact must not be in any cave */
      if (result_artefact->caveID != 0)
        throwf(BAD_ARGUMENT_EXCEPTION,
         "merge_artefacts_special: result artefact %d is in cave %d",
               result_artefact->artefactID, result_artefact->caveID);

      /* result_artefact must not be in any movement */
      temp_result = db_query(database, "SELECT * FROM Event_movement"
               " WHERE artefactID = %d",
           result_artefact->artefactID);

      if (db_result_num_rows(temp_result) != 0)
        throwf(BAD_ARGUMENT_EXCEPTION,
         "merge_artefacts_special: result artefact %d is moving",
               result_artefact->artefactID);

      /* check: result_artefact has to be uninitiated */
      /* XXX can this ever happen (it is not in a cave)? */
      if (result_artefact->initiated != ARTEFACT_UNINITIATED)
        uninitiate_artefact(database, result_artefact->artefactID);
    }

    /* now merge them */
    merge_artefacts(database,
                    key_artefact->caveID,
                    key_artefact->artefactID,
                    lock_artefact->artefactID,
                    result_artefact->artefactID);
    return 1;
  }

  return 0;
}
示例#12
0
/*
 * merge_artefacts_general
 * Throws exception if needed conditions are not as they should have been.
 */
int merge_artefacts_general (db_t *database,
           const struct Artefact *key_artefact,
           struct Artefact *lock_artefact,
           struct Artefact *result_artefact)
{
  db_result_t *result;
  db_result_t *temp_result;
  int row;
  dstring_t *ds;

  /* now get possible merging formulas */
  ds = dstring_new("SELECT * FROM Artefact_merge_general "
            "WHERE keyClassID = %d",
        key_artefact->artefactClassID);
  result = db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "merge_artefact_general: %s", dstring_str(ds));

  /* check for a suitable merging */
  while ((row = db_result_next_row(result)))
  {
    /* special rules:
     *
     * lockClassID = 0
     * no lock artefact needed
     *
     * keyClassID = lockClassID
     * unlocks if at least one other initiated artefact
     * of the same class exists
     *
     * resultClassID = 0
     * key artefact and one present instance of the lockClass vanish
     */

    /* lock artefact */
    lock_artefact->artefactClassID =
    db_result_get_int(result, "lockClassID");

    if (lock_artefact->artefactClassID == 0)
      break;

    /* implicit checks:
     * - lock artefact has to be different from the key artefact
     * - lock artefact has to be in the same cave as the key artefact
     * - lock artefact has to be initiated
     * - lock artefact has be of the specified class
     */
    ds = dstring_new("SELECT artefactID FROM " DB_TABLE_ARTEFACT
             " WHERE artefactID != %d"
             " AND artefactClassID = %d"
             " AND caveID = %d"
             " AND initiated = %d",
         key_artefact->artefactID,
         lock_artefact->artefactClassID,
         key_artefact->caveID,
         ARTEFACT_INITIATED);
    temp_result = db_query_dstring(database, ds);

    debug(DEBUG_ARTEFACT, "merge_artefact_general: %s", dstring_str(ds));

    /* is there a suitable lock artefact? */
    if (db_result_next_row(temp_result))
    {
      lock_artefact->artefactID = db_result_get_int(temp_result, "artefactID");
      lock_artefact->caveID     = key_artefact->caveID;
      lock_artefact->initiated  = ARTEFACT_INITIATED;
      break;
    }
  }

  if (row)
  {
    /* result artefact */
    result_artefact->artefactClassID =
    db_result_get_int(result, "resultClassID");

    if (result_artefact->artefactClassID != 0)
      result_artefact->artefactID =
    new_artefact(database, result_artefact->artefactClassID);

    /* now merge them */
    merge_artefacts(database,
                    key_artefact->caveID,
                    key_artefact->artefactID,
                    lock_artefact->artefactID,
                    result_artefact->artefactID);
    return 1;
  }

  return 0;
}
示例#13
0
static void
SV_Punish (int mode)
{
	int         i;
	double      mins = 0.5;
	qboolean    all = false, done = false;
	client_t    *cl = 0;
	dstring_t  *text = dstring_new();
	const char *cmd = 0;
	const char *cmd_do = 0;
	//FIXME const char *cmd_undo = 0;
	int         field_offs = 0;

	switch (mode) {
		case 0:
			cmd = "cuff";
			cmd_do = "cuffed";
			//FIXME cmd_undo = "un-cuffed";
			field_offs = field_offset (client_t, cuff_time);
			break;
		case 1:
			cmd = "mute";
			cmd_do = "muted";
			//FIXME cmd_undo = "can speak";
			field_offs = field_offset (client_t, lockedtill);
			break;
	}

	if (Cmd_Argc () != 2 && Cmd_Argc () != 3) {
		SV_Printf ("usage: %s <name/userid/ALL> [minutes]\n"
				   "       (default = 0.5, 0 = cancel cuff).\n", cmd);
		return;
	}

	if (strequal (Cmd_Argv (1), "ALL")) {
		all = true;
	} else {
		cl = SV_Match_User (Cmd_Argv (1));
	}
	if (!all && !cl)
		return;
	if (Cmd_Argc () == 3) {
		mins = atof (Cmd_Argv (2));
		if (mins < 0.0 || mins > MAXPENALTY)
			mins = MAXPENALTY;
	}
	if (cl) {
		*(double *)((char *)cl + field_offs) = realtime + mins * 60.0;
		if (mins) {
			dsprintf (text, "You are %s for %.1f minutes\n\n"
					 "reconnecting won't help...\n", cmd_do, mins);
			MSG_ReliableWrite_Begin (&cl->backbuf, svc_centerprint,
									 2 + strlen (text->str));
			MSG_ReliableWrite_String (&cl->backbuf, text->str);
		}
	}
	if (all) {
		for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
			if (cl->state < cs_zombie)
				continue;
			*(double *)((char *)cl + field_offs) = realtime + mins * 60.0;
			done = true;
			if (mins) {
				dsprintf (text, "You are %s for %.1f minutes\n\n"
						 "reconnecting won't help...\n", cmd_do, mins);
				MSG_ReliableWrite_Begin (&cl->backbuf, svc_centerprint,
										 2 + strlen (text->str));
				MSG_ReliableWrite_String (&cl->backbuf, text->str);
			}
		}
	}
	if (done) {
		if (mins)
			SV_BroadcastPrintf (PRINT_HIGH, "%s %s for %.1f minutes.\n",
								all? "All Users" : cl->name, cmd_do, mins);
		else
			SV_BroadcastPrintf (PRINT_HIGH, "%s %s.\n",
								all? "All Users" : cl->name, cmd_do);
	}
	dstring_delete (text);
}
示例#14
0
void
gl_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m,
								   int _s, int extra)
{
	dstring_t  *cache, *fullpath;
	unsigned char model_digest[MDFOUR_DIGEST_BYTES];
	unsigned char mesh_digest[MDFOUR_DIGEST_BYTES];
	int         i, j;
	int        *cmds;
	QFile      *f;
	qboolean    remesh = true;
	qboolean    do_cache = false;

	aliasmodel = m;
	paliashdr = hdr;

	cache = dstring_new ();
	fullpath = dstring_new ();

	if (!gl_alias_render_tri->int_val) {

		if (gl_mesh_cache->int_val
			&& gl_mesh_cache->int_val <= paliashdr->mdl.numtris) {
			do_cache = true;

			mdfour (model_digest, (unsigned char *) _m, _s);

			// look for a cached version
			dstring_copystr (cache, "glquake/");
			dstring_appendstr (cache, m->name);
			QFS_StripExtension (m->name + strlen ("progs/"),
							cache->str + strlen ("glquake/"));
			dstring_appendstr (cache, ".qfms");

			QFS_FOpenFile (cache->str, &f);
			if (f) {
				unsigned char d1[MDFOUR_DIGEST_BYTES];
				unsigned char d2[MDFOUR_DIGEST_BYTES];
				struct mdfour md;
				int			len, vers;
				int         nc = 0, no = 0;
				int        *c = 0, *vo = 0;

				memset (d1, 0, sizeof (d1));
				memset (d2, 0, sizeof (d2));

				Qread (f, &vers, sizeof (int));
				Qread (f, &len, sizeof (int));
				Qread (f, &nc, sizeof (int));
				Qread (f, &no, sizeof (int));

				if (vers == 1 && (nc + no) == len) {
					c = malloc (((nc + 1023) & ~1023) * sizeof (c[0]));
					vo = malloc (((no + 1023) & ~1023) * sizeof (vo[0]));
					if (!c || !vo)
						Sys_Error ("gl_mesh.c: out of memory");
					Qread (f, c, nc * sizeof (c[0]));
					Qread (f, vo, no * sizeof (vo[0]));
					Qread (f, d1, MDFOUR_DIGEST_BYTES);
					Qread (f, d2, MDFOUR_DIGEST_BYTES);
					Qclose (f);

					mdfour_begin (&md);
					mdfour_update (&md, (unsigned char *) &vers, sizeof(int));
					mdfour_update (&md, (unsigned char *) &len, sizeof(int));
					mdfour_update (&md, (unsigned char *) &nc, sizeof(int));
					mdfour_update (&md, (unsigned char *) &no, sizeof(int));
					mdfour_update (&md, (unsigned char *) c, nc * sizeof (c[0]));
					mdfour_update (&md, (unsigned char *) vo, no * sizeof (vo[0]));
					mdfour_update (&md, d1, MDFOUR_DIGEST_BYTES);
					mdfour_result (&md, mesh_digest);

					if (memcmp (d2, mesh_digest, MDFOUR_DIGEST_BYTES) == 0
						&& memcmp (d1, model_digest, MDFOUR_DIGEST_BYTES) == 0) {
						remesh = false;
						numcommands = nc;
						numorder = no;
						if (numcommands > commands_size) {
							if (commands)
								free (commands);
							commands_size = (numcommands + 1023) & ~1023;
							commands = c;
						} else {
							memcpy (commands, c, numcommands * sizeof (c[0]));
							free(c);
						}
						if (numorder > vertexorder_size) {
							if (vertexorder)
								free (vertexorder);
							vertexorder_size = (numorder + 1023) & ~1023;
							vertexorder = vo;
						} else {
							memcpy (vertexorder, vo, numorder * sizeof (vo[0]));
							free (vo);
						}
					}
				}
			}
		}
		if (remesh) {
			// build it from scratch
			Sys_MaskPrintf (SYS_DEV, "meshing %s...\n", m->name);

			BuildTris ();					// trifans or lists

			if (do_cache) {
				// save out the cached version
				dsprintf (fullpath, "%s/%s", qfs_gamedir->dir.def, cache->str);
				f = QFS_WOpen (fullpath->str, 9);

				if (f) {
					struct mdfour md;
					int         vers = 1;
					int         len = numcommands + numorder;

					mdfour_begin (&md);
					mdfour_update (&md, (unsigned char *) &vers, sizeof (int));
					mdfour_update (&md, (unsigned char *) &len, sizeof (int));
					mdfour_update (&md, (unsigned char *) &numcommands,
								   sizeof (int));
					mdfour_update (&md, (unsigned char *) &numorder, sizeof (int));
					mdfour_update (&md, (unsigned char *) commands,
								   numcommands * sizeof (commands[0]));
					mdfour_update (&md, (unsigned char *) vertexorder,
								   numorder * sizeof (vertexorder[0]));
					mdfour_update (&md, model_digest, MDFOUR_DIGEST_BYTES);
					mdfour_result (&md, mesh_digest);

					Qwrite (f, &vers, sizeof (int));
					Qwrite (f, &len, sizeof (int));
					Qwrite (f, &numcommands, sizeof (int));
					Qwrite (f, &numorder, sizeof (int));
					Qwrite (f, commands, numcommands * sizeof (commands[0]));
					Qwrite (f, vertexorder, numorder * sizeof (vertexorder[0]));
					Qwrite (f, model_digest, MDFOUR_DIGEST_BYTES);
					Qwrite (f, mesh_digest, MDFOUR_DIGEST_BYTES);
					Qclose (f);
				}
			}
		}

		// save the data out
		paliashdr->poseverts = numorder;

		cmds = Hunk_Alloc (numcommands * sizeof (int));
		paliashdr->commands = (byte *) cmds - (byte *) paliashdr;
		memcpy (cmds, commands, numcommands * sizeof (int));

	} else {
		tex_coord_t *tex_coord;

		numorder = 0;
		for (i=0; i < pheader->mdl.numtris; i++) {
			add_vertex(triangles[i].vertindex[0]);
			add_vertex(triangles[i].vertindex[1]);
			add_vertex(triangles[i].vertindex[2]);
		}
		paliashdr->poseverts = numorder;

		tex_coord = Hunk_Alloc (numorder * sizeof(tex_coord_t));
		paliashdr->tex_coord = (byte *) tex_coord - (byte *) paliashdr;
		for (i=0; i < numorder; i++) {
			float s, t;
			int k;
			k = vertexorder[i];
			s = stverts[k].s;
			t = stverts[k].t;
			if (!triangles[i/3].facesfront && stverts[k].onseam)
				s += pheader->mdl.skinwidth / 2;	// on back side
			s = (s + 0.5) / pheader->mdl.skinwidth;
			t = (t + 0.5) / pheader->mdl.skinheight;
			tex_coord[i].st[0] = s;
			tex_coord[i].st[1] = t;
		}
	}

	if (extra) {
		trivertx16_t *verts;
		verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts
							* sizeof (trivertx16_t));
		paliashdr->posedata = (byte *) verts - (byte *) paliashdr;
		for (i = 0; i < paliashdr->numposes; i++) {
			trivertx_t *pv = poseverts[i];
			for (j = 0; j < numorder; j++) {
				trivertx16_t v;
				// convert MD16's split coordinates into something a little
				// saner. The first chunk of vertices is fully compatible with
				// IDPO alias models (even the scale). The second chunk is the
				// fractional bits of the vertex, giving 8.8. However, it's
				// easier for us to multiply everything by 256 and adjust the
				// model scale appropriately
				VectorMultAdd (pv[vertexorder[j] + hdr->mdl.numverts].v,
							   256, pv[vertexorder[j]].v, v.v);
				v.lightnormalindex =
					poseverts[i][vertexorder[j]].lightnormalindex;
				*verts++ = v;
			}
		}
	} else {
		trivertx_t *verts;
		verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts
							* sizeof (trivertx_t));
		paliashdr->posedata = (byte *) verts - (byte *) paliashdr;
		for (i = 0; i < paliashdr->numposes; i++) {
			for (j = 0; j < numorder; j++)
				*verts++ = poseverts[i][vertexorder[j]];
		}
	}
	dstring_delete (cache);
	dstring_delete (fullpath);
}
示例#15
0
/*
	CF_Open

	cfopen opens a file, either for reading or writing (not both).
	returns a file descriptor >= 0 on success, < 0 on failure.
	mode is either r or w.
*/
int
CF_Open (const char *path, const char *mode)
{
	char *j;
	dstring_t *fullpath = dstring_new ();
	int desc, oldsize, i;
	QFile *file;

	if (cf_openfiles >= CF_MAXFILES) {
		return -1;
	}

	// check for paths with ..
	if (strequal (path, "..")
		|| !strncmp (path, "../", 3)
		|| strstr (path, "/../")
		|| (strlen (path) >= 3
			&& strequal (path + strlen (path) - 3, "/.."))) {
		return -1;
	}

	if (!(strequal(mode, "w") || strequal(mode, "r") || strequal(mode, "a"))) {
		return -1;
	}

	if (mode[0] == 'w' && cf_maxsize < 0) { // can't even delete if quota < 0
		return -1;
	}

	dsprintf (fullpath, "%s/%s/%s", qfs_gamedir->dir.def, CF_DIR, path);

	j = fullpath->str + strlen (fullpath->str) - strlen (path);
	for (i = 0; path[i]; i++, j++) // strcpy, but force lowercase
		*j = tolower ((byte) path[i]);
	*j = '\0';

	if (CF_AlreadyOpen (fullpath->str, mode[0])) {
		dstring_delete (fullpath);
		return -1;
	}

	if (mode[0] == 'w')
		oldsize = CF_GetFileSize (fullpath->str);
	else
		oldsize = 0;

	file = QFS_Open (fullpath->str, mode);
	if (file) {
		if (cf_openfiles >= cf_filepcount) {
			cf_filepcount++;
			cf_filep = realloc (cf_filep, sizeof (cf_file_t) * cf_filepcount);
			if (!cf_filep) {
				Sys_Error ("CF_Open: memory allocation error!");
			}
			cf_filep[cf_filepcount - 1].file = 0;
		}

		for (desc = 0; cf_filep[desc].file; desc++)
			;
		cf_filep[desc].path = fullpath->str;
		cf_filep[desc].file = file;
		cf_filep[desc].buf = 0;
		cf_filep[desc].size = 0;
		cf_filep[desc].writtento = 0;
		cf_filep[desc].mode = mode[0];

		cf_cursize -= oldsize;
		cf_openfiles++;

		return desc;
	}
	return -1;
}
示例#16
0
int init_tt(PluginManager* pm) {
    dstring rolename = dstring_new("tt");
    PluginManager_register_role_hook(pm, rolename, tt_role_hook);
    dstring_free(rolename);
    return 1;
}
示例#17
0
/*
 * This function is responsible for all the movement.
 *
 * @params database  the function needs this link to the DB
 * @params result    current movement event (from DB)
 */
void movement_handler (db_t *database, db_result_t *result)
{
  int movementID;
  int target_caveID;
  int source_caveID;
  const char *speed_factor;

  time_t event_start;
  time_t event_end;
  const char *return_start;
  char return_end[TIMESTAMP_LEN];

  struct Cave cave1;
  struct Cave cave2;
  struct Player player1;
  struct Player player2;
  struct Relation relation1;
  struct Relation relation2;

  int i;
  int units[MAX_UNIT];
  int resources[MAX_RESOURCE];
  int takeover_multiplier;
  int change_owner;
  int isFarming = 0;
  
  Battle *battle;
  dstring_t *ds;
  double spy_result;

  /* time related issues */
  const float *battle_bonus;

  /* artefacts */
  int artefact = 0;
  int artefact_def = 0;
  int artefact_id = 0;
  int lostTo = 0;

  int body_count = 0;
  int attacker_lose = 0;
  int defender_lose = 0;
  int defender_va_lose = 0;

  int war_points_attacker = 0;
  int war_points_defender = 0;
  int war_points_sender = 0;
  int war_points_show = 0;

	int  takeover = 0;
  debug(DEBUG_TICKER, "entering function movement_handler()");

  /* get movement id and target/source cave id */
  movementID    = db_result_get_int(result, "movementID");
  target_caveID = db_result_get_int(result, "target_caveID");
  source_caveID = db_result_get_int(result, "source_caveID");
  speed_factor  = db_result_get_string(result, "speedFactor");

  /* get event_start and event_end */
  event_start  = db_result_get_gmtime(result, "start");
  return_start = db_result_get_string(result, "end");
  event_end    = make_time_gm(return_start);
  make_timestamp_gm(return_end, event_end + (event_end - event_start));

  /* get resources, units and artefact id */
  get_resource_list(result, resources);
  get_unit_list(result, units);
  artefact = db_result_get_int(result, "artefactID");

  /* TODO reduce number of queries */
  get_cave_info(database, source_caveID, &cave1);
  get_cave_info(database, target_caveID, &cave2);

  if (cave1.player_id)
    get_player_info(database, cave1.player_id, &player1);
  else{	/* System */
    memset(&player1, 0, sizeof player1);
    player1.tribe = "";
  }
  if (cave2.player_id == cave1.player_id)
    player2 = player1;
  else if (cave2.player_id)
    get_player_info(database, cave2.player_id, &player2);
  else{	/* System */
    memset(&player2, 0, sizeof player2);
    player2.tribe = "";
  }
  debug(DEBUG_TICKER, "caveID = %d, movementID = %d",
	target_caveID, movementID);

  /**********************************************************************/
  /*** THE INFAMOUS GIANT SWITCH ****************************************/
  /**********************************************************************/

  switch (movementID) {

    /**********************************************************************/
    /*** ROHSTOFFE BRINGEN ************************************************/
    /**********************************************************************/
    case ROHSTOFFE_BRINGEN:

      /* record in takeover table */
      ds = dstring_new("UPDATE " DB_TABLE_CAVE_TAKEOVER " SET ");

      for (i = 0; i < MAX_RESOURCE; ++i)
	dstring_append(ds, "%s%s = %s + %d", i > 0 ? "," : "",
		resource_type[i]->dbFieldName,
		resource_type[i]->dbFieldName, resources[i]);

      dstring_append(ds, " WHERE caveID = %d AND playerID = %d",
		     target_caveID, cave1.player_id);

      db_query_dstring(database, ds);
			if(db_affected_rows(database)!=0){
							takeover=1;
			}
	/* put resources into cave */
	dstring_set(ds, "UPDATE " DB_TABLE_CAVE " SET ");

	for (i = 0; i < MAX_RESOURCE; ++i)
	  dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "",
		  resource_type[i]->dbFieldName,
		  resource_type[i]->dbFieldName, 
			(takeover==1)?resources[i] * TAKEOVER_RESOURCE_SAVE_PERCENTAGE / 100:resources[i],
		  function_to_sql(resource_type[i]->maxLevel));

	dstring_append(ds, " WHERE caveID = %d", target_caveID);

	db_query_dstring(database, ds);

      if (artefact > 0)
	put_artefact_into_cave(database, artefact, target_caveID);

      /* send all units back */
      dstring_set(ds, "INSERT INTO Event_movement"
		      " (caveID, target_caveID, source_caveID, movementID,"
		      " speedFactor, start, end");

      for (i = 0; i < MAX_UNIT; ++i)
	dstring_append(ds, ",%s", unit_type[i]->dbFieldName);

      dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s'",
	      source_caveID, source_caveID, target_caveID, RUECKKEHR,
	      speed_factor, return_start, return_end);

      for (i = 0; i < MAX_UNIT; ++i)
	dstring_append(ds, ",%d", units[i]);

      dstring_append(ds, ")");

      db_query_dstring(database, ds);

      /* generate trade report and receipt for sender */
      trade_report(database, &cave1, &player1, &cave2, &player2,
		   resources, NULL, artefact);
      break;

    /**********************************************************************/
    /*** EINHEITEN/ROHSTOFFE VERSCHIEBEN **********************************/
    /**********************************************************************/
    case VERSCHIEBEN:
      get_relation_info(database, player1.tribe, player2.tribe, &relation1);
      /*überprüfen ob sender und versender eine kriegsbeziehung haben */
      if(!(isVerschiebenAllowed(database, &player1, &player2, &relation1) ||
	      isTakeoverableCave(database, target_caveID))){
        //bewegung umdrehen//
	    /* send remaining units back */
	    ds = dstring_new("INSERT INTO Event_movement"
		  " (caveID, target_caveID, source_caveID, movementID,"
		  " speedFactor, start, end, artefactID");

	    for (i = 0; i < MAX_RESOURCE; ++i)
	      dstring_append(ds, ",%s", resource_type[i]->dbFieldName);
	    for (i = 0; i < MAX_UNIT; ++i)
	      dstring_append(ds, ",%s", unit_type[i]->dbFieldName);

	    dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d",
		  source_caveID, source_caveID, target_caveID, RUECKKEHR,
		  speed_factor, return_start, return_end, artefact);

	    for (i = 0; i < MAX_RESOURCE; ++i)
	      dstring_append(ds, ",%d", resources[i]);
	    for (i = 0; i < MAX_UNIT; ++i)
	      dstring_append(ds, ",%d", units[i]);

	    dstring_append(ds, ")");

	    db_query_dstring(database, ds);
	    break;
      }
      /* record in takeover table */
      ds = dstring_new("UPDATE " DB_TABLE_CAVE_TAKEOVER " SET ");

      for (i = 0; i < MAX_RESOURCE; ++i)
	    dstring_append(ds, "%s%s = %s + %d", i > 0 ? "," : "",
		  resource_type[i]->dbFieldName,
		  resource_type[i]->dbFieldName, resources[i]);

      dstring_append(ds, " WHERE caveID = %d AND playerID = %d",
	      target_caveID, cave1.player_id);

      db_query_dstring(database, ds);
      if(db_affected_rows(database)!=0){
              takeover=1;
      }

      /* put resources and units into cave */
      dstring_set(ds, "UPDATE " DB_TABLE_CAVE " SET ");

      for (i = 0; i < MAX_RESOURCE; ++i)
        dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "",
                       resource_type[i]->dbFieldName,
                       resource_type[i]->dbFieldName, 
                      (takeover==1)?resources[i] * TAKEOVER_RESOURCE_SAVE_PERCENTAGE / 100:resources[i],
                      function_to_sql(resource_type[i]->maxLevel));
      for (i = 0; i < MAX_UNIT; ++i){
        war_points_sender += ((struct Unit *)unit_type[i])->warpoints * units[i];
        dstring_append(ds, ",%s = %s + %d",
	               unit_type[i]->dbFieldName,
	               unit_type[i]->dbFieldName, units[i]);
        }
        if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){
          war_points_update_verschieben(database, player1.tribe, player2.tribe, -1* war_points_sender);
        }
        dstring_append(ds, " WHERE caveID = %d", target_caveID);

	    db_query_dstring(database, ds);

      if (artefact > 0)
	put_artefact_into_cave(database, artefact, target_caveID);

      /* generate trade report and receipt for sender */
      trade_report(database, &cave1, &player1, &cave2, &player2,
		   resources, units, artefact);
      break;

    /**********************************************************************/
    /*** RUECKKEHR ********************************************************/
    /**********************************************************************/
    case RUECKKEHR:

      /* put resources into cave */
      ds = dstring_new("UPDATE " DB_TABLE_CAVE " SET ");

      for (i = 0; i < MAX_RESOURCE; ++i)
	dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "",
		resource_type[i]->dbFieldName,
		resource_type[i]->dbFieldName, resources[i],
		function_to_sql(resource_type[i]->maxLevel));

      for (i = 0; i < MAX_UNIT; ++i)
	dstring_append(ds, ",%s = %s + %d",
		 unit_type[i]->dbFieldName,
		 unit_type[i]->dbFieldName, units[i]);

      dstring_append(ds, " WHERE caveID = %d", target_caveID);

      db_query_dstring(database, ds);

      if (artefact > 0)
	put_artefact_into_cave(database, artefact, target_caveID);

      /* generate return report */
      return_report(database, &cave1, &player1, &cave2, &player2,
		    resources, units, artefact);
      break;

    /**********************************************************************/
    /*** ANGREIFEN ********************************************************/
    /**********************************************************************/
    case ANGREIFEN:

      /* beginner protection active in target cave? */
      if (cave_is_protected(&cave2))
      {
	   debug(DEBUG_BATTLE, "Is protected Cave");
	/* send remaining units back */
	ds = dstring_new("INSERT INTO Event_movement"
			 " (caveID, target_caveID, source_caveID, movementID,"
			 " speedFactor, start, end, artefactID");

	for (i = 0; i < MAX_RESOURCE; ++i)
	  dstring_append(ds, ",%s", resource_type[i]->dbFieldName);
	for (i = 0; i < MAX_UNIT; ++i)
	  dstring_append(ds, ",%s", unit_type[i]->dbFieldName);

	dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d",
		       source_caveID, source_caveID, target_caveID, RUECKKEHR,
		       speed_factor, return_start, return_end, artefact);

	for (i = 0; i < MAX_RESOURCE; ++i)
	  dstring_append(ds, ",%d", resources[i]);
	for (i = 0; i < MAX_UNIT; ++i)
	  dstring_append(ds, ",%d", units[i]);

	dstring_append(ds, ")");

	db_query_dstring(database, ds);
     debug(DEBUG_BATTLE,"End Handle Protected Cave attack");
	/* create and send reports */
	protected_report(database, &cave1, &player1, &cave2, &player2);
	break;
      }

      /* get relations between the two players' tribes */
      get_relation_info(database, player1.tribe, player2.tribe, &relation1);
      get_relation_info(database, player2.tribe, player1.tribe, &relation2);
      debug(DEBUG_BATTLE, "Relationtypes: %d and %d", relation1.relationType,
            relation2.relationType);

      battle = battle_create(1, 1);
      battle_bonus = get_battle_bonus();

      debug(DEBUG_BATTLE, "entering prepare_battle");
      /* prepare structs for battle, exceptions are uncaught! */
      prepare_battle(database,
		     battle,
		     &player1,
		     &player2,
		     &cave1, &cave2, battle_bonus, 0,
		     units, resources,
		     &artefact, &artefact_def,
		     &relation1, &relation2);

      /* calculate the fame */
      /* Calculatin is diferent if the battle was just pure farming*/
      isFarming = check_farming(database, cave2.artefacts, &player1,
			      &player2, &relation1);
      if( relation1.relationType == RELATION_TYPE_WAR){
	battle->isWar = 1;
      }

      /* calculate battle result */
      calcBattleResult(battle, &cave2, 0);

      /* change artefact ownership */
      debug(DEBUG_BATTLE, "entering change artefact");
      after_battle_change_artefact_ownership(
	database, battle->winner, &artefact, &artefact_id, &artefact_def,
	target_caveID, &cave2, &lostTo);

      /* attackers artefact (if any) is stored in variable artefact,
	 artefact_id is id of the artefact that changed owner (or 0) */

      /* no relation -> attacker get negative fame*/
      debug(DEBUG_BATTLE, "Relation Type %d",relation1.relationType);

      /* construct attacker update */
      debug(DEBUG_BATTLE, "entering attacker update");
      after_battle_attacker_update(database, player1.player_id, battle,
				   source_caveID, target_caveID, speed_factor,
				   return_start, return_end, artefact,
				   &relation1);

      /* defender update: exception still uncaught (better leave) */
      debug(DEBUG_BATTLE, "entering defender update");
      after_battle_defender_update(database, player2.player_id,
				   battle, target_caveID, &relation2);

 
      /* Farming update */
      if(isFarming){
        increaseFarming(database, player1.player_id);
      }

      /* reset DB_TABLE_CAVE_TAKEOVER */
      ds = dstring_new("UPDATE " DB_TABLE_CAVE_TAKEOVER " SET status = 0");

      for (i = 0; i < MAX_RESOURCE; ++i)
	dstring_append(ds, ",%s = 0", resource_type[i]->dbFieldName);

      dstring_append(ds, " WHERE caveID = %d AND playerID = %d",
		  target_caveID, cave1.player_id);

      db_query_dstring(database, ds);

      /* cave takeover by battle */
      if (battle->winner == FLAG_ATTACKER &&
	  ((struct Terrain *)terrain_type[cave2.terrain])->takeoverByCombat) {
	db_query(database, "UPDATE " DB_TABLE_CAVE " SET playerID = %d"
			   " WHERE caveID = %d",
		 cave1.player_id, target_caveID);

	db_query(database, "DELETE FROM Event_science WHERE caveID = %d",
		 target_caveID);

	science_update_caves(database, cave1.player_id);
      }
     //bodycount calculate
      attacker_lose = bodycount_calculate(battle, FLAG_DEFENDER);
      defender_lose = bodycount_calculate(battle, FLAG_ATTACKER);
      defender_va_lose = bodycount_va_calculate(battle);

      bodycount_update( database, player1.player_id, defender_lose);
      bodycount_update( database, player2.player_id, attacker_lose);
      if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){
	war_points_show = 1;
        war_points_attacker = (defender_lose>10||defender_va_lose>5?war_points_calculate(battle,FLAG_ATTACKER):0);
        war_points_defender = (attacker_lose>10?war_points_calculate(battle,FLAG_DEFENDER):0);

        war_points_update(database, player1.tribe, player2.tribe, war_points_attacker, war_points_defender);
      }

      /* create and send reports */
      battle_report(database, &cave1, &player1, &cave2, &player2, battle,
		    artefact_id, lostTo, 0, 0, &relation1, &relation2,
		    war_points_show, war_points_attacker, war_points_defender);
      break;

    /**********************************************************************/
    /*** Spionieren *******************************************************/
    /**********************************************************************/
    case SPIONAGE:

      /* generate spy report */
      spy_result = spy_report(database, &cave1, &player1, &cave2, &player2,
			      resources, units, artefact);

      if (spy_result == 1)
      {
	/* send all units back */
	ds = dstring_new("INSERT INTO Event_movement"
			 " (caveID, target_caveID, source_caveID, movementID,"
			 " speedFactor, start, end, artefactID");

	for (i = 0; i < MAX_RESOURCE; ++i)
	  dstring_append(ds, ",%s", resource_type[i]->dbFieldName);
	for (i = 0; i < MAX_UNIT; ++i)
	  dstring_append(ds, ",%s", unit_type[i]->dbFieldName);

	dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d",
		source_caveID, source_caveID, target_caveID, RUECKKEHR,
		speed_factor, return_start, return_end, artefact);

	for (i = 0; i < MAX_RESOURCE; ++i)
	  dstring_append(ds, ",%d", resources[i]);
	for (i = 0; i < MAX_UNIT; ++i)
	  dstring_append(ds, ",%d", units[i]);

	dstring_append(ds, ")");

	db_query_dstring(database, ds);
      }
      else
      {
	/* send remaining units back */
	int count = 0;

	ds = dstring_new("INSERT INTO Event_movement"
			 " (caveID, target_caveID, source_caveID, movementID,"
			 " speedFactor, start, end, artefactID");

	for (i = 0; i < MAX_UNIT; ++i)
	  dstring_append(ds, ",%s", unit_type[i]->dbFieldName);

	dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d",
		source_caveID, source_caveID, target_caveID, RUECKKEHR,
		speed_factor, return_start, return_end, artefact);

	for (i = 0; i < MAX_UNIT; ++i)
	{
	  int num = units[i] * spy_result;

	  dstring_append(ds, ",%d", num);
	  count += num;
      body_count += units[i] - num;
	}

	dstring_append(ds, ")");

	if (count)
	  db_query_dstring(database, ds);

	/* put resources into cave */
	ds = dstring_new("UPDATE " DB_TABLE_CAVE " SET ");

	for (i = 0; i < MAX_RESOURCE; ++i)
	  dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "",
		  resource_type[i]->dbFieldName,
		  resource_type[i]->dbFieldName, resources[i],
		  function_to_sql(resource_type[i]->maxLevel));

	dstring_append(ds, " WHERE caveID = %d", target_caveID);

	db_query_dstring(database, ds);

	if (artefact > 0)
	  put_artefact_into_cave(database, artefact, target_caveID);
      }
      bodycount_update(database, player2.player_id, body_count);
      break;

    /**********************************************************************/
    /*** UEBERNEHMEN ******************************************************/
    /**********************************************************************/
    case TAKEOVER:

      /* secure or protected target gave? */
      if (cave2.secure || cave_is_protected(&cave2))
      {
	/* send remaining units back */
	ds = dstring_new("INSERT INTO Event_movement"
			 " (caveID, target_caveID, source_caveID, movementID,"
			 " speedFactor, start, end, artefactID");

	for (i = 0; i < MAX_RESOURCE; ++i)
	  dstring_append(ds, ",%s", resource_type[i]->dbFieldName);
	for (i = 0; i < MAX_UNIT; ++i)
	  dstring_append(ds, ",%s", unit_type[i]->dbFieldName);

	dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d",
		       source_caveID, source_caveID, target_caveID, RUECKKEHR,
		       speed_factor, return_start, return_end, artefact);

	for (i = 0; i < MAX_RESOURCE; ++i)
	  dstring_append(ds, ",%d", resources[i]);
	for (i = 0; i < MAX_UNIT; ++i)
	  dstring_append(ds, ",%d", units[i]);

	dstring_append(ds, ")");

	db_query_dstring(database, ds);

	/* create and send reports */
	/* FIXME use different message in report (protected -> secure) */
	protected_report(database, &cave1, &player1, &cave2, &player2);
	break;
      }

      get_relation_info(database, player1.tribe, player2.tribe, &relation1);
      get_relation_info(database, player2.tribe, player1.tribe, &relation2);

      battle = battle_create(1, 1);

      battle_bonus = get_battle_bonus();
      takeover_multiplier = get_takeover_multiplier(&cave2);

      /* prepare structs for battle, exceptions are uncaught! */
      prepare_battle(database,
		     battle,
		     &player1,
		     &player2,
		     &cave1, &cave2, battle_bonus, takeover_multiplier,
		     units, resources,
		     &artefact, &artefact_def,
		     &relation1, &relation2);

      /* calculate battle result */
      /*bei ner übernahme kein resi klau möglich*/
      calcBattleResult(battle, &cave2, 1);

      /* change artefact ownership */
      after_battle_change_artefact_ownership(
        database, battle->winner, &artefact, &artefact_id, &artefact_def,
	    target_caveID, &cave2, &lostTo);

      /* attackers artefact (if any) is stored in variable artefact,
	     artefact_id is id of the artefact that changed owner (or 0) */

      /* defender update: exception still uncaught (better leave) */
      after_battle_defender_update(database, player2.player_id,
				   battle, target_caveID, &relation2);


     int war1 = get_tribe_at_war(database,player1.tribe);
     int war2 = get_tribe_at_war(database,player2.tribe);

      /* attacker won:  put survivors into cave, change owner
       * attacker lost: send back survivors */
      change_owner =
          battle->winner == FLAG_ATTACKER && cave2.player_id != PLAYER_SYSTEM &&
          player1.max_caves > get_number_of_caves(database, player1.player_id) &&
          ((relation1.relationType == RELATION_TYPE_WAR &&
 	    relation2.relationType == RELATION_TYPE_WAR) ||
	    (!war1 && !war2) ||
           (strcasecmp(player1.tribe, player2.tribe) == 0)); // Spieler im selben stamm
     //bodycount calculate
      attacker_lose = bodycount_calculate(battle, FLAG_DEFENDER);
      defender_lose = bodycount_calculate(battle, FLAG_ATTACKER);
      defender_va_lose = bodycount_va_calculate(battle);

      bodycount_update( database, player1.player_id, defender_lose);
      bodycount_update( database, player2.player_id, attacker_lose);
      if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){
        war_points_show = 1;
        war_points_attacker = (defender_lose>10||defender_va_lose>5?war_points_calculate(battle,FLAG_ATTACKER):0);
        war_points_defender = (attacker_lose>10?war_points_calculate(battle,FLAG_DEFENDER):0);

      }

      if (change_owner){
        debug(DEBUG_TAKEOVER, "change owner of cave %d to new owner %d",
	          target_caveID, cave1.player_id);
        takeover_cave(database, target_caveID, cave1.player_id,return_start);
        after_takeover_attacker_update(database, player1.player_id,
		                               battle, target_caveID,
                                       artefact, &relation1);
        if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){
          war_points_attacker += WAR_POINTS_FOR_TAKEOVER;
        }
      } else { /* send survivors back */
        debug(DEBUG_TAKEOVER, "send back attacker's suvivors");
        after_battle_attacker_update(database, player1.player_id, battle,
				     source_caveID, target_caveID, speed_factor,
				     return_start, return_end, artefact,
				     &relation1);
      }
      if(relation1.relationType == RELATION_TYPE_PRE_WAR || relation1.relationType == RELATION_TYPE_WAR){
        war_points_update(database, player1.tribe, player2.tribe, war_points_attacker, war_points_defender);
      }

      /* create and send reports */
      battle_report(database, &cave1, &player1, &cave2, &player2, battle,
		    artefact_id, lostTo, change_owner, 1 + takeover_multiplier,
		    &relation1, &relation2,war_points_show, war_points_attacker, war_points_defender);
     //bodycount calculate


      bodycount_update( database, player1.player_id, defender_lose);
      bodycount_update( database, player2.player_id, attacker_lose);
      break;

    default:
      throw(BAD_ARGUMENT_EXCEPTION, "movement_handler: unknown movementID");
  }

  /**********************************************************************/
  /*** END OF THE INFAMOUS GIANT SWITCH *********************************/
  /**********************************************************************/

  debug(DEBUG_TICKER, "leaving function movement_handler()");
}