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

📄 npc_stoneserviceman.c

📁 石器时代8.0服务端完整源代码。可以直接编译
💻 C
📖 第 1 页 / 共 3 页
字号:
//Terry 2001/09/27
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "char.h"
#include "object.h"
#include "char_base.h"
#include "npcutil.h"
#include "lssproto_serv.h"
#include "npc_stoneserviceman.h"
#include "readmap.h"
#include "battle.h"
#include "log.h"
#include "enemy.h"
#include "configfile.h"

#ifdef _SERVICE
#define LOOP_TIME 100		//0.1秒(进入loop function 的时间)
#define MAX_AP_MSG 128		// 接收AP送来讯息的最大数

// socket struct
struct socketaddr_in
{
  u_short sin_family;
  u_short sin_port;
  u_long  sin_addr;
  char    sin_zero[8];
};

// 接收AP传来的讯息
typedef struct _MSG
{
  int nAid;		// nAid => 流水号*10 + 讯息代号(_AP_CLIENT_MESSAGE)
  int nIndex;		// NPC的index值
  int nLen;		// 讯息长度
  LPList Data;		// 实际资料
  int bIsUse;		// 这个讯息是否有使用过
}Msg,*pMsg;
Msg g_APMsg[MAX_AP_MSG];
        
// 动作id        
enum _AP_CLIENT_MESSAGE
{
  Cli_CHECKPLAYER,  //要求AP对玩家是否有购买产品的确认  0
  AP_CHECKPLAYER,   //AP回应玩家是否有购买产品
  Cli_YES,          //玩家确定要将奖品拿走
  Cli_CANCEL,	    //通知AP把lock栏位清为0             
  Cli_GET,	    //通知AP给物品
  AP_GET,	    //AP回应物品			5
  Cli_CONNECT,      //测试是否有连到AP
  AP_CONNECT,       //AP回应
  AP_ERROR          //AP有错误				
};

// NPC的工作变数
enum
{
  NPC_WORK_FLAG1   	 = CHAR_NPCWORKINT2,	//flag1
  NPC_WORK_FLAG2   	 = CHAR_NPCWORKINT3,	//flag2
  NPC_WORK_FLAG3   	 = CHAR_NPCWORKINT4,	//flag3
  NPC_WORK_TIMEOUT 	 = CHAR_NPCWORKINT5,	//time out 时间
  NPC_WORK_STATE   	 = CHAR_NPCWORKINT6,	//目前执行状态
  NPC_WORK_START   	 = CHAR_NPCWORKINT7,	//开始计时flag
  NPC_WORK_LEAVE_COUNT   = CHAR_NPCWORKINT8,	//玩家talk时间计时
  NPC_WORK_TOINDEX 	 = CHAR_NPCWORKINT9,	//玩家的index值
  NPC_WORK_SERIALNUM     = CHAR_NPCWORKINT10,   //流水号
  NPC_WORK_ISUSE   	 = CHAR_NPCWORKINT11,	//目前NPC是否有玩家在使用
};

// 执行的状态
enum
{
  SERVICE_STATE_1,	// check 有没有和AP连线中 
  SERVICE_STATE_2,	// 向AP取得玩家有无买产品
  SERVICE_STATE_3,	// 取得要给玩家的东西的资料
  SERVICE_STATE_4	// end state
};
                                                                
extern int errno;

int g_nServiceSocket;
int g_EnableService = 0;
char g_ApID[32];
struct socketaddr_in server_sin;
struct sockaddr      temp;
unsigned short g_Port;

static void NPC_StoneServiceMan_selectWindow(int meindex,int toindex,int num,int select);
extern int GetSerialNum(void);
static int flag = 1;

/*********************************
* 初始化
*********************************/
BOOL NPC_StoneServiceManInit(int meindex )
{
  char npcarg[NPC_UTIL_GETARGSTR_BUFSIZE];
  
  if(NPC_Util_GetArgStr(meindex,npcarg,sizeof(npcarg)) == NULL){
    print("StoneServiceMan:GetArgStrErr");
    return FALSE;
  }

  CHAR_setInt(meindex,CHAR_LOOPINTERVAL,LOOP_TIME);
  CHAR_setInt(meindex,CHAR_WHICHTYPE,CHAR_TYPESTONESERVICEMAN);
  CHAR_setWorkInt(meindex,NPC_WORK_FLAG1,1);
  CHAR_setWorkInt(meindex,NPC_WORK_FLAG2,1);
  CHAR_setWorkInt(meindex,NPC_WORK_FLAG3,1);
  CHAR_setWorkInt(meindex,NPC_WORK_TIMEOUT,0);
  CHAR_setWorkInt(meindex,NPC_WORK_STATE,SERVICE_STATE_2);
  CHAR_setWorkInt(meindex,NPC_WORK_START,0);  
  CHAR_setWorkInt(meindex,NPC_WORK_TOINDEX,-1);
  CHAR_setWorkInt(meindex,NPC_WORK_ISUSE,0);
  CHAR_setWorkInt(meindex,NPC_WORK_LEAVE_COUNT,0);
  CHAR_setWorkInt(meindex,NPC_WORK_SERIALNUM,-1);

  g_EnableService = getEnableService();
  
  //连线到AP在init时只做一次
  if(flag && g_EnableService){
    strcpy(g_ApID,getApID());
		g_Port = getApPort();
    bzero(g_APMsg,sizeof(g_APMsg));
    ConnectToAP();//连线到AP
    flag = 0;
  }
  
  return TRUE;
}

void NPC_StoneServiceManTalked(int meindex,int talkerindex,char *szMes,int color)
{
  if(CHAR_getInt(talkerindex,CHAR_WHICHTYPE) != CHAR_TYPEPLAYER) return;
  if(NPC_Util_isFaceToFace(talkerindex,meindex,1) == FALSE) return;
  NPC_StoneServiceMan_selectWindow(meindex,talkerindex,0,-1);
}

static void NPC_StoneServiceMan_selectWindow(int meindex,int toindex,int num,int select)
{
  char npcarg[NPC_UTIL_GETARGSTR_BUFSIZE];
  char token[1024],buf[128],*pUserid;
  int buttontype = 0, windowtype = 0, windowno = 0,nAid,nLen;
  int fd = getfdFromCharaIndex(toindex);
  char Data[3][32],talk[128];
  int i,j,k,Ret;
  LPList DataList = NULL,Kill = NULL;

	
  if(fd == -1) 
  {
    print("getfd err\n");
    return;
  }
	
  if(NPC_Util_GetArgStr(meindex,npcarg,sizeof(npcarg)) == NULL)
  {
    print("GetArgStrErr");
    return ;
  }
  
  token[0] = '\0';

  //如果不使用石器服务员的功能
  if(!g_EnableService)
  {
    sprintf(token,"\n 请到此星系的最後一颗星球使用此服务,谢谢!");
    buttontype = WINDOW_BUTTONTYPE_OK;
    windowtype = WINDOW_MESSAGETYPE_MESSAGE;
    windowno = CHAR_WINDOWTYPE_SERVICE_WAIT;
    
    lssproto_WN_send(fd,windowtype,buttontype,windowno,
                     CHAR_getWorkInt(meindex,CHAR_WORKOBJINDEX),
		     token);    
    return;
  }
  
  //如果这个玩家是第一个和NPC讲话
  if(CHAR_getWorkInt(meindex,NPC_WORK_ISUSE) == 0 && 
     CHAR_getWorkInt(meindex,NPC_WORK_TOINDEX) == -1)
  {
    //记住第一个和NPC讲话的是谁
    CHAR_setWorkInt(meindex,NPC_WORK_TOINDEX,toindex);
    //设定为NPC正在使用中
    CHAR_setWorkInt(meindex,NPC_WORK_ISUSE,1);
  }
  //如果是第二个以後和NPC讲话的人
  else if(CHAR_getWorkInt(meindex,NPC_WORK_ISUSE) == 1 &&
          CHAR_getWorkInt(meindex,NPC_WORK_TOINDEX) != toindex)
  {
    sprintf(token,"\n 正在服务其他玩家中,请稍等...");
    buttontype = WINDOW_BUTTONTYPE_OK;
    windowtype = WINDOW_MESSAGETYPE_MESSAGE;
    windowno = CHAR_WINDOWTYPE_SERVICE_WAIT;
    
    lssproto_WN_send(fd,windowtype,buttontype,windowno,
                     CHAR_getWorkInt(meindex,CHAR_WORKOBJINDEX),
		     token);    
    return;
  }
  if(flag) 
  {
    ConnectToAP();
	flag = 0;
  }
  switch(num)
  {
  case 0:
  case 1:
    //取得玩家的id
    pUserid = CHAR_getChar(toindex,CHAR_CDKEY);
    if(CHAR_getWorkInt(meindex,NPC_WORK_FLAG2) == 1)
    {
	  if(pUserid == NULL || SendToAP(Cli_CHECKPLAYER,meindex,1,pUserid,NULL) == 0)
      {
        if(NPC_Util_GetStrFromStrWithDelim(npcarg,"SysBusyMsg",buf,sizeof(buf)) == NULL) return;
        sprintf(token,"\n %s",buf);
        buttontype = WINDOW_BUTTONTYPE_OK;
        windowtype = WINDOW_MESSAGETYPE_MESSAGE;
        windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
        break;
      }
      CHAR_setWorkInt(meindex,NPC_WORK_FLAG2,0);
      CHAR_setWorkInt(meindex,NPC_WORK_START,1);
    }
    if(CHAR_getWorkInt(meindex,NPC_WORK_STATE) == SERVICE_STATE_2)
    {
			// 超过五秒time out
      if(CHAR_getWorkInt(meindex,NPC_WORK_TIMEOUT) >= 50)
      {
        close(g_nServiceSocket);
        flag = 1;
        sprintf(token,"\n 重新与系统取得连线...");
        buttontype = WINDOW_BUTTONTYPE_OK;
        windowtype = WINDOW_MESSAGETYPE_MESSAGE;
        windowno = CHAR_WINDOWTYPE_SERVICE_CONTINUE;
				CHAR_setWorkInt(meindex,NPC_WORK_TIMEOUT,0);
				CHAR_setWorkInt(meindex,NPC_WORK_FLAG2,1);
				CHAR_setWorkInt(meindex,NPC_WORK_START,0);
        break;
      }
      if((Ret = RecvFromAP(&nAid,meindex,&nLen,&DataList)) == -1)
      {
        sprintf(token,"\n 等待回应...");
        buttontype = WINDOW_BUTTONTYPE_OK;
        windowtype = WINDOW_MESSAGETYPE_MESSAGE;
        windowno = CHAR_WINDOWTYPE_SERVICE_CONTINUE;
        break;
      }
      else 
      {
        for(i=0;i<nLen;i++)
        {
          strcpy(Data[i],DataList->Data);
          Kill = DataList;
          DataList = DataList->Next;
          if(Kill != NULL) free(Kill);
        }
        // 使用过的讯息清空
        bzero(&g_APMsg[Ret],sizeof(Msg));
      }
      if(nAid == AP_CHECKPLAYER)
      {
        switch(atoi(Data[0]))
        {
        case 0: //没买
          if(NPC_Util_GetStrFromStrWithDelim(npcarg,"ErrMsg",buf,sizeof(buf)) == NULL) return;
          sprintf(token,"\n %s",buf);
          buttontype = WINDOW_BUTTONTYPE_OK;
          windowtype = WINDOW_MESSAGETYPE_MESSAGE;
          windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;     
        break;
        case 1: //有买
          if(NPC_Util_GetStrFromStrWithDelim(npcarg,"MainMsg",buf,sizeof(buf)) == NULL) return;
          sprintf(token,"5\n %s"
                        "\n 你要将%s"
												"\n 的奖品给这个角色吗?\n"
                        "\n"
                        "\n                    《 确  定 》"
  	                    "\n"
        	              "\n                    《 取  消 》",
                        buf,Data[1]);
          buttontype = WINDOW_BUTTONTYPE_NONE;
          windowtype = WINDOW_MESSAGETYPE_SELECT;
          windowno = CHAR_WINDOWTYPE_SERVICE_START; 
        break;
        //另一个角色正在使用中
        case 2:
          sprintf(token,"\n 目前您的另一个角色正在领取.");
          buttontype = WINDOW_BUTTONTYPE_OK;
          windowtype = WINDOW_MESSAGETYPE_MESSAGE;
          windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
          break;
				//玩家的奖品已领完
				case 3:
					sprintf(token,"\n 您的奖品已经领完了!!");
          buttontype = WINDOW_BUTTONTYPE_OK;
          windowtype = WINDOW_MESSAGETYPE_MESSAGE;
          windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
          break;
        break;
        }
      }
      else
      {
        sprintf(token,"\n 系统讯息错误!!(%d)",nAid);
        buttontype = WINDOW_BUTTONTYPE_OK;
        windowtype = WINDOW_MESSAGETYPE_MESSAGE;
        windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
      }
      CHAR_setWorkInt(meindex,NPC_WORK_TIMEOUT,0);
      CHAR_setWorkInt(meindex,NPC_WORK_FLAG2,1);
    }
    else
    {
      sprintf(token,"\n 等待回应...");
      buttontype = WINDOW_BUTTONTYPE_OK;
      windowtype = WINDOW_MESSAGETYPE_MESSAGE;
      windowno = CHAR_WINDOWTYPE_SERVICE_CONTINUE;
    }
  break;
  case 2:
    //取得玩家的id
    pUserid = CHAR_getChar(toindex,CHAR_CDKEY);
    if(CHAR_getWorkInt(meindex,NPC_WORK_FLAG3) == 1){
      if(pUserid == NULL || SendToAP(Cli_GET,meindex,1,pUserid,NULL) == 0){
        if(NPC_Util_GetStrFromStrWithDelim(npcarg,"SysBusyMsg",buf,sizeof(buf)) == NULL) return;
        sprintf(token,"\n %s",buf);
        buttontype = WINDOW_BUTTONTYPE_OK;
        windowtype = WINDOW_MESSAGETYPE_MESSAGE;
        windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
        break;
      }
			CHAR_setWorkInt(meindex,NPC_WORK_START,1);
      CHAR_setWorkInt(meindex,NPC_WORK_FLAG3,0);
    }
    if(CHAR_getWorkInt(meindex,NPC_WORK_STATE) == SERVICE_STATE_3){
			// 超过五秒time out
      if(CHAR_getWorkInt(meindex,NPC_WORK_TIMEOUT) >= 50){
        close(g_nServiceSocket);
        flag = 1;
        sprintf(token,"\n 重新与系统取得连线...");
        buttontype = WINDOW_BUTTONTYPE_OK;
        windowtype = WINDOW_MESSAGETYPE_MESSAGE;
        windowno = CHAR_WINDOWTYPE_SERVICE_CONTINUE;
				CHAR_setWorkInt(meindex,NPC_WORK_TIMEOUT,0);
				CHAR_setWorkInt(meindex,NPC_WORK_FLAG3,1);

⌨️ 快捷键说明

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