⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 offclient.cpp

📁 2002年
💻 CPP
字号:
//#ifdef _OffClient
/* -*- Off Client -*-
 * Custom initialization and destruction
 *	Only one thread is created to both parse server info and do decision-making.
 *  To capture the desired cycle in ExecuteAI.
 */

#include "client.h"
#include "stopwatch.h"
#include "log.h"
#include "worldmodel.h"
#include <fstream>
#include "perceptron.h"
#include "skill.h"
#include "agent.h"
#include "utils.h"
#include "netif.h"

using namespace World;

#ifndef WIN32
#include <time.h>
#include <pthread.h>
#include <iostream>
#endif

#ifdef WIN32
	#include <process.h>
	HANDLE sigoffclient = NULL;
#else // _LINUX
	pthread_t sigoffclient;	
#endif



FILE *fp_mat = NULL;		

#ifdef WIN32
unsigned int WINAPI OffProcWindows(LPVOID lpParameter);
#endif

void * OffProc(void *);

void ExecuteAI();
void Assitant(char* buf);
int Readline(char* &buf);

/*This function is called in the same order with behave() in normal client mode.
*/
void ExecuteAI(){	
	Agent::behave();
}


void Assistant(char* buf){
	int type;
	int  subtype, time;
	float x,y, power;
	UniformTime ut;
	TIME_T tt;
	
	int width, quality;

	type = get_int(&buf);

	switch(type){
	case Ass_Vinfo:
		subtype = get_int(&buf);
		visualsystem.Vinfo_coming = bool(subtype == 1);
		if(visualsystem.Vinfo_coming){
			visualsystem.Vcominginfo_angle = get_float(&buf);
			visualsystem.Vcominginfo_width = get_float(&buf);
		}
		break;
	case Ass_ActEffect:
		subtype = get_int(&buf);
		time = get_int(&buf);
		switch(subtype){
		case CMD_kick:
			x = get_float(&buf); y = get_float(&buf); power = get_float(&buf);
			Skill::action.SetKickEffect(x, y, power,  time);
			break;
		case CMD_dash:
			x = get_float(&buf); y = get_float(&buf); power = get_float(&buf);
			Skill::action.SetDashEffect(x, y, power,  time);
			break;
		case CMD_turn:
			x = get_float(&buf);
			Skill::action.SetTurnEffect(x, time);
			break;
		case CMD_turn_neck:
			x = get_float(&buf);
			Skill::action.SetTurnNeckEffect(x, time);
			break;
		case CMD_change_view:
			Self.NextViewCycle = get_int(&buf);
			sensory.NextViewWidth = VIEWWIDTH(get_int(&buf));
		}
		break;
	case Ass_Chview:

#ifdef WIN32
		sscanf(buf, "%d %I64d %d %d", &subtype, &ut.QuadPart, &width, &quality);
#else // _LINUX
		sscanf(buf, "%d %lld %d %d", &subtype, &ut.QuadPart, &width, &quality);
#endif
		tt = stopwatch.DeFormatTime(ut);
		stopwatch.SetRawData_Event(tt,  subtype);
		if(!situation.ClockStopped){
			float nextsight_time;
			int LatestTime = sensory.LatestTime;
			//note: if no change view, the nextviewwidth is just my current viewwidth.
			nextsight_time = sensory.SightInterval((VIEWWIDTH)width, (VIEWQUALITY)quality) - stopwatch.MsFromEvent(SW_Event_ChangeView, SW_CycleStart, LatestTime);
			
			Self.NextViewCycle=LatestTime + nextsight_time / ServerParam::simulator_step;
		}
		break;
	}
}

void SetWatch(char* buf){
	UniformTime tmp;
#ifdef WIN32
	sscanf(buf,"%I64d", &tmp.QuadPart);
#else //_LINUX
	sscanf(buf,"%lld", &tmp.QuadPart);
#endif
	//set into cache time identified in the following parse
	TIME_T t = stopwatch.DeFormatTime(tmp);
	stopwatch.SetRawData_Cache(t);
}
/*Read a valid line from mat file, return state and valuable buffer point. 
 *
 * Return Value:
 *		-1:fail
 *		LM_Init: init info
 *		LM_Info: Msg received from server
 *		LM_Ctrl: Log when Ctrl proc start to update
 *		buf: point to valuable msg (log label has been stripped)
 */
int Readline(char* &buf){
	while(true){
		if(fgets(StringBuffer::matbuf, MAXMESG, fp_mat) == NULL) 
			return -1;
		//string format "(p%d,t%d)[label] info..."
		buf = StringBuffer::matbuf;
		//advance to '['
		while(*buf != '[' && *buf != 0) buf ++;
		if(*buf != 0) break;
	}
	buf ++;
	//look label
	char* channel_str[] = LM_Channel_Label;
	for(int i=0; i<LM_Num_Channels; i++){
		int len = strlen(channel_str[i]);
		if(!strncmp(buf, channel_str[i], len)){
			buf += len;
			buf ++;
			return LM_Channel(i);
		}
	}
	return -1;
}


#ifdef WIN32
/*Offclient  process	
 *		Simulate Match on the basis of mat file
 */
unsigned int WINAPI OffProcWindows(LPVOID lpParameter){
	OffProc(NULL);
	_endthreadex(0);
	return 0;
}
#endif


extern int NoResponseFromServer;

void * OffProc(void *){
	char* buf;
        int state;
        while(true){
                state = Readline(buf);
                switch(state){
                case LM_Init:
                case LM_Info:
                        sensory.Parse(buf);
                        break;
                case LM_Upd:
                        DoLog(LOG_NONE, "******** Cycle %d **********", sensory.LatestTime);
                        sensory.Update();

                        break;
                case LM_Exec:
                        ExecuteAI();
                        break;
                case LM_Ass:
                        Assistant(buf);
                        break;
                case LM_Watch:
                        SetWatch(buf);
                        break;
                case -1:
#ifdef WIN32
                        PostMessage(hWND, WM_DESTROY, 0, 0);
#else //_LINUX
						pthread_exit(0);
#endif
                        return 0;
                default :
                        break;
                }
        }
}

/* Initialization of OffClient Mode
 *		prepare the mat file, and create thread.
 */
int InitInstance_E(){
	Log::InitLog();
	Network::sock = NULL;

	fp_mat = fopen(ClientParam::matfile, "r");
	if(fp_mat == NULL) return 0;

	char* buf;
//1)read team name from mat file
	if(Readline(buf) != LM_Init) return 0;
	int buflen = strlen(buf);
	buf[buflen-1] = 0; //skip the newline character
	strcpy(MyTeamName, buf);
	MyTeamNameLen = strlen(MyTeamName);

//2)read init infos (including server's and players' param)
	if(Readline(buf) != LM_Init) return 0;
	if(!sensory.Parse_initialize_message(buf)){
		return 0;
	}
	my_error("Connected!");

	Agent::Initialize();

#ifdef WIN32
	sigoffclient = (HANDLE)_beginthreadex(NULL, 0, OffProcWindows, NULL, 0, NULL);
	if(sigoffclient == NULL){
		my_error("create thread off error");
		return false;
	}

	SetThreadPriority(sigoffclient,THREAD_PRIORITY_BELOW_NORMAL);
#else // _LINUX
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
	if (pthread_create(&sigoffclient, &attr, OffProc, NULL) != 0){
                my_error("create thread error");
                return false;    
	}
	
	pthread_join(sigoffclient, NULL);
#endif

	return true;
}

/* Desctruction
 *		Terminate thread and Close mat file.
 */
void destruction_E(){	
#ifdef WIN32
	if(sigoffclient){
		CloseHandle(sigoffclient);
	}
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -