Beispiel #1
0
int		user_read(t_server *server, t_client *cl)
{
  char		buf[RSIZE];
  char		aligned[cl->rb->size + 1];
  char		*tmp;
  char		*save;
  ssize_t	retv;

  tmp = aligned;
  if ((retv = read(cl->fd, buf, RSIZE)) <= 0)
    return (disconnect_user(server, cl));
  fill_ringbuffer(cl->rb, buf, retv);
  if ((tmp = get_buff(cl->rb)) == NULL)
    return (-1);
  save = tmp;
  while ((retv = get_char_pos(tmp, '\n')) != -1)
    {
      tmp[retv] = '\0';
      if (process_input(server, cl, tmp) < -1)
	{
	  queue_push(&cl->queue, "ko\n");
	  return (disconnect_user(server, cl));
	}
      tmp = &tmp[retv + 1];
    }
  update_ringbuffer(cl->rb, save, tmp);
  return (0);
}
Beispiel #2
0
/*** login_time_out is the length of time someone can idle at login, 
     user_idle_time is the length of time they can idle once logged in. 
     Also ups users total login time. ***/
void check_idle_and_timeout(void)
{
	UR_OBJECT user=user_first,next;
	int tm;

	set_crash();
/* Use while loop here instead of for loop for when user structure gets
   destructed, we may lose ->next link and crash the program */
	while (user) {
		next=user->next;
		if (user->type==CLONE_TYPE) {  user=next;  continue;  }
		user->total_login+=amsys->heartbeat; 
		if (user->level>amsys->time_out_maxlevel) {  user=next;  continue;  }
		tm=(int)(time(0) - user->last_input);
		if (user->login && tm>=amsys->login_idle_time) {
			write_user(user, login_timeout);
			disconnect_user(user);
			user=next;
			continue;
			}
		if (syspp->auto_afk
		    && tm>=syspp->auto_afk_time
		    && !user->afk
		    && !user->login) {
			afk(user, auto_afk_mesg);
			user=next;
			continue;
			}
		if (user->warned) {
			if (tm<amsys->user_idle_time-60) {  user->warned=0;  continue;  }
			if (tm>=amsys->user_idle_time) {
				write_user(user,"\n\n\07~FR~OL~LI*** You have been timed out. ***\n\n");
				disconnect_user(user);
				user=next;
				continue;
				}
			}
		if ((!user->afk || (user->afk && amsys->time_out_afks)) 
		    && !user->login 
		    && !user->warned
		    && tm>=amsys->user_idle_time-60) {
#ifdef PUEBLO
			audioprompt(user, 4, 0);
#endif
			vwrite_user(user,"\n\07~FY~OL~LI*** POZOR - Mas 1 minutu aby si nieco napisal%s lebo ta vydrbkam !***\n\n", grm_gnd(4, user->gender));
			user->warned=1;
			}
		user=next;
		}
}
Beispiel #3
0
void kick_user(client client, char *msg) {
	if (client.isAlive) {
		send(client.fd, recv_msg[KICKED], strlen(recv_msg[KICKED]), MSG_NOSIGNAL);
		send(client.fd, msg, strlen(msg), MSG_NOSIGNAL);
		disconnect_user(client);
	}
}
Beispiel #4
0
int		user_write(t_server *server, t_client *cl)
{
  ssize_t	wsize;
  ssize_t	msglen;
  char		*msg;

  msg = queue_front(cl->queue);
  msglen = strlen(msg);
  if ((wsize = write(cl->fd, msg, msglen)) <= 0)
    {
      perror("");
      return (disconnect_user(server, cl));
    }
  if (wsize < msglen)
    shift_msg(msg, wsize);
  else
    queue_pop(&cl->queue);
  return (0);
}
Beispiel #5
0
/**
 * Server Main Loop
 * @param server Server Listening Socket
 * @return OS Error Code
 */
int server_loop(int server)
{
	// Set Running Status
	_status = 1;
	
	// Create Empty Status Logfile
	update_status();
	
	// Handling Loop
	while(_status == 1)
	{
		// Login Block
		{
			// Login Result
			int loginresult = 0;
			
			// Login Processing Loop
			do
			{
				// Prepare Address Structure
				struct sockaddr_in addr;
				socklen_t addrlen = sizeof(addr);
				memset(&addr, 0, sizeof(addr));
				
				// Accept Login Requests
				// loginresult = accept4(server, (struct sockaddr *)&addr, &addrlen, SOCK_NONBLOCK);
				
				// Alternative Accept Approach (some Linux Kernel don't support the accept4 Syscall... wtf?)
				loginresult = accept(server, (struct sockaddr *)&addr, &addrlen);
				if(loginresult != -1)
				{
					// Switch Socket into Non-Blocking Mode
					change_blocking_mode(loginresult, 1);
				}
				
				// Login User (Stream)
				if(loginresult != -1) login_user_stream(loginresult, addr.sin_addr.s_addr);
			} while(loginresult != -1);
		}
		
		// Receive Data from Users
		SceNetAdhocctlUserNode * user = _db_user;
		while(user != NULL)
		{
			// Next User (for safe delete)
			SceNetAdhocctlUserNode * next = user->next;
			
			// Receive Data from User
			int recvresult = recv(user->stream, user->rx + user->rxpos, sizeof(user->rx) - user->rxpos, 0);
			
			// Connection Closed or Timed Out
			if(recvresult == 0 || (recvresult == -1 && errno != EAGAIN && errno != EWOULDBLOCK) || get_user_state(user) == USER_STATE_TIMED_OUT)
			{
				// Logout User
				logout_user(user);
			}
			
			// Received Data (or leftovers in RX-Buffer)
			else if(recvresult > 0 || user->rxpos > 0)
			{
				// New Incoming Data
				if(recvresult > 0)
				{
					// Move RX Pointer
					user->rxpos += recvresult;
					
					// Update Death Clock
					user->last_recv = time(NULL);
				}
				
				// Waiting for Login Packet
				if(get_user_state(user) == USER_STATE_WAITING)
				{
					// Valid Opcode
					if(user->rx[0] == OPCODE_LOGIN)
					{
						// Enough Data available
						if(user->rxpos >= sizeof(SceNetAdhocctlLoginPacketC2S))
						{
							// Clone Packet
							SceNetAdhocctlLoginPacketC2S packet = *(SceNetAdhocctlLoginPacketC2S *)user->rx;
							
							// Remove Packet from RX Buffer
							clear_user_rxbuf(user, sizeof(SceNetAdhocctlLoginPacketC2S));
							
							// Login User (Data)
							login_user_data(user, &packet);
						}
					}
					
					// Invalid Opcode
					else
					{
						// Notify User
						uint8_t * ip = (uint8_t *)&user->resolver.ip;
						printf("Invalid Opcode 0x%02X in Waiting State from %u.%u.%u.%u.\n", user->rx[0], ip[0], ip[1], ip[2], ip[3]);
						
						// Logout User
						logout_user(user);
					}
				}
				
				// Logged-In User
				else if(get_user_state(user) == USER_STATE_LOGGED_IN)
				{
					// Ping Packet
					if(user->rx[0] == OPCODE_PING)
					{
						// Delete Packet from RX Buffer
						clear_user_rxbuf(user, 1);
					}
					
					// Group Connect Packet
					else if(user->rx[0] == OPCODE_CONNECT)
					{
						// Enough Data available
						if(user->rxpos >= sizeof(SceNetAdhocctlConnectPacketC2S))
						{
							// Cast Packet
							SceNetAdhocctlConnectPacketC2S * packet = (SceNetAdhocctlConnectPacketC2S *)user->rx;
							
							// Clone Group Name
							SceNetAdhocctlGroupName group = packet->group;
							
							// Remove Packet from RX Buffer
							clear_user_rxbuf(user, sizeof(SceNetAdhocctlConnectPacketC2S));
							
							// Change Game Group
							connect_user(user, &group);
						}
					}
					
					// Group Disconnect Packet
					else if(user->rx[0] == OPCODE_DISCONNECT)
					{
						// Remove Packet from RX Buffer
						clear_user_rxbuf(user, 1);
						
						// Leave Game Group
						disconnect_user(user);
					}
					
					// Network Scan Packet
					else if(user->rx[0] == OPCODE_SCAN)
					{
						// Remove Packet from RX Buffer
						clear_user_rxbuf(user, 1);
						
						// Send Network List
						send_scan_results(user);
					}
					
					// Chat Text Packet
					else if(user->rx[0] == OPCODE_CHAT)
					{
						// Enough Data available
						if(user->rxpos >= sizeof(SceNetAdhocctlChatPacketC2S))
						{
							// Cast Packet
							SceNetAdhocctlChatPacketC2S * packet = (SceNetAdhocctlChatPacketC2S *)user->rx;
							
							// Clone Buffer for Message
							char message[64];
							memset(message, 0, sizeof(message));
							strncpy(message, packet->message, sizeof(message) - 1);
							
							// Remove Packet from RX Buffer
							clear_user_rxbuf(user, sizeof(SceNetAdhocctlChatPacketC2S));
							
							// Spread Chat Message
							spread_message(user, message);
						}
					}
					
					// Invalid Opcode
					else
					{
						// Notify User
						uint8_t * ip = (uint8_t *)&user->resolver.ip;
						printf("Invalid Opcode 0x%02X in Logged-In State from %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u).\n", user->rx[0], (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3]);

						// Logout User
						logout_user(user);
					}
				}
			}
			
			// Move Pointer
			user = next;
		}
		
		// Prevent needless CPU Overload (1ms Sleep)
		usleep(1000);
	}
	
	// Free User Database Memory
	free_database();
	
	// Close Server Socket
	close(server);
	
	// Return Success
	return 0;
}
Beispiel #6
0
/*
 * Shoot another user... Fun! Fun! Fun! ;)
 */
void
shoot_user(UR_OBJECT user)
{
  UR_OBJECT user2;
  RM_OBJECT rm;
  int prob1, prob2;

  rm = get_room_full(amsys->default_shoot);
  if (!rm) {
    write_user(user, "There is nowhere that you can shoot.\n");
    return;
  }
  if (user->room != rm) {
    vwrite_user(user,
                "Do not be shooting in a public place. Go to the ~OL%s~RS to play.\n",
                rm->name);
    return;
  }
  if (word_count < 2) {
    if (!user->bullets) {
      vwrite_room_except(rm, user,
                         "%s~RS's gun goes *click* as they pull the trigger.\n",
                         user->recap);
      write_user(user, "Your gun goes *click* as you pull the trigger.\n");
      return;
    }
    vwrite_room_except(rm, user, "%s~RS fires their gun off into the air.\n",
                       user->recap);
    write_user(user, "You fire your gun off into the air.\n");
    --user->bullets;
    return;
  }
  prob1 = rand() % 100;
  prob2 = rand() % 100;
  user2 = get_user_name(user, word[1]);
  if (!user2) {
    write_user(user, notloggedon);
    return;
  }
  if (!user->vis) {
    write_user(user,
               "Be fair! At least make a decent target--do not be invisible!\n");
    return;
  }
  if ((!user2->vis && user2->level < user->level) || user2->room != rm) {
    write_user(user, "You cannot see that person around here.\n");
    return;
  }
  if (user == user2) {
    write_user(user, "Watch it! You might shoot yourself in the foot!\n");
    return;
  }
  if (!user->bullets) {
    vwrite_room_except(rm, user,
                       "%s~RS's gun goes *click* as they pull the trigger.\n",
                       user->recap);
    write_user(user, "Your gun goes *click* as you pull the trigger.\n");
    return;
  }
  if (prob1 > prob2) {
    vwrite_room(rm, "A bullet flies from %s~RS's gun and ~FR~OLhits~RS %s.\n",
                user->recap, user2->recap);
    --user->bullets;
    ++user->hits;
    --user2->hps;
    write_user(user2, "~FR~OLYou have been hit!\n");
    write_user(user, "~FG~OLGood shot!\n");
    if (user2->hps < 1) {
      ++user2->deaths;
      vwrite_user(user,
                  "\nYou have won the shoot out, %s~RS is dead!  You may now rejoice!\n",
                  user2->recap);
      write_user(user2,
                 "\nYou have received a fatal wound, and you feel your warm ~FRblood ~OLooze~RS out of you.\n");
      write_user(user2, "The room starts to fade and grow grey...\n");
      write_user(user2,
                 "In the bleak mist of Death's shroud you see a man walk towards you.\n");
      write_user(user2,
                 "The man is wearing a tall black hat, and a wide grin...\n\n");
      user2->hps = 5 * user2->level;
      write_syslog(SYSLOG, 1, "%s shot dead by %s\n", user2->name,
                   user->name);
      disconnect_user(user2);
      ++user->kills;
      user->hps = user->hps + 5;
      return;
    }
    return;
  }
  vwrite_room(rm,
              "A bullet flies from %s~RS's gun and ~FG~OLmisses~RS %s~RS.\n",
              user->recap, user2->recap);
  --user->bullets;
  ++user->misses;
  write_user(user2, "~FGThat was a close shave!\n");
  write_user(user, "~FRYou could not hit the side of a barn!\n");
}
Beispiel #7
0
/*
 * Delete a user
 */
void
delete_user(UR_OBJECT user, int this_user)
{
    char name[USER_NAME_LEN + 1];
    UR_OBJECT u;

    if (this_user) {
        /*
         * User structure gets destructed in disconnect_user(), need to keep a
         * copy of the name
         */
        strcpy(name, user->name);
        write_user(user, "\n~FR~LI~OLACCOUNT DELETED!\n");
        vwrite_room_except(user->room, user, "~OL~LI%s commits suicide!\n",
                user->name);
        write_syslog(SYSLOG, 1, "%s SUICIDED.\n", name);
        disconnect_user(user);
        clean_files(name);
        rem_user_node(name);
        return;
    }
    if (word_count < 2) {
        write_user(user, "Usage: nuke <user>\n");
        return;
    }
    *word[1] = toupper(*word[1]);
    if (!strcmp(word[1], user->name)) {
        write_user(user,
                "Trying to delete yourself is the eleventh sign of madness.\n");
        return;
    }
    if (get_user(word[1])) {
        /* Safety measure just in case. Will have to .kill them first */
        write_user(user,
                "You cannot delete a user who is currently logged on.\n");
        return;
    }
    u = create_user();
    if (!u) {
        vwrite_user(user, "%s: unable to create temporary user object.\n",
                syserror);
        write_syslog(SYSLOG | ERRLOG, 0,
                "ERROR: Unable to create temporary user object in delete_user().\n");
        return;
    }
    strcpy(u->name, word[1]);
    if (!load_user_details(u)) {
        write_user(user, nosuchuser);
        destruct_user(u);
        destructed = 0;
        return;
    }
    if (u->level >= user->level) {
        write_user(user,
                "You cannot delete a user of an equal or higher level than yourself.\n");
        destruct_user(u);
        destructed = 0;
        return;
    }
    clean_files(u->name);
    rem_user_node(u->name);
    vwrite_user(user, "\07~FR~OL~LIUser %s deleted!\n", u->name);
    write_syslog(SYSLOG, 1, "%s DELETED %s.\n", user->name, u->name);
    destruct_user(u);
    destructed = 0;
}
Beispiel #8
0
/*リクエストを処理するに値する*/
int connection_do_request(CONNECTION_DATA* con,int content_length){
	FILE* log_file;
	TCPsocket* c_sock = &con->socket;
	char* recv;
	int idx = 0;
	int size;
	int total_size = 0;
	USER_INFO* info;
	CRYPT* crypt;
	//リクエスト関係
	Uint32 user_id;
	Uint32 action_code;
	//非暗号化データ
	user_id = NetUtl_recvInt(c_sock);
	idx+=4;
	action_code = NetUtl_recvInt(c_sock);
	idx+=4;
	content_length -= idx;
	idx = 0;
	//この時点でユーザ検索
	info = get_user(user_id);
	if(info == null){//ユーザが見つからない
		char ch;
		int size = 0;
		log_file = lock_log_file();
		time_output();
		ip_output(con->ip);
		fprintf(log_file,"User NOT FOUND ID:%08x\n",user_id);
		unlock_log_file();
		//最後まで受信しないと、エラーになりがち。
		while(size < content_length && SDLNet_TCP_Recv(*c_sock, &ch, 1) == 1){
			size++;
		}
		return false;
	}

	//接続
	if(!connect_user(info)){
		char ch;
		int size = 0;
		//ログ
		log_file = lock_log_file();
		time_output();
		ip_output(con->ip);
		fprintf(log_file,"(%s)Already connected.\n",info->name);
		unlock_log_file();
		//最後まで受信しないと、エラーになりがち。
		while(size < content_length && SDLNet_TCP_Recv(*c_sock, &ch, 1) == 1){
			size++;
		}
		return false;
	}

	//鍵を使うと宣言
	crypt = &info->crypt;
	startCrypt(crypt);

	//暗号化データ受信
	recv = malloc(content_length);
	while((size = recvCrypt(crypt,c_sock,
					&recv[total_size],content_length-total_size)) > 0){
		total_size += size;
		if(total_size >= content_length){
			break;
		}
	}
	//サイズがあわない。
	if(total_size < content_length){
		log_file = lock_log_file();
		time_output();
		ip_output(con->ip);
		fprintf(log_file,"(%s)Invalid Size Request.\n",info->name);
		unlock_log_file();
		//処理
		free(recv);
		disconnect_user(info);
		//KICKED
		connection_return_req_data_header(con,CONNECTION_ACTION_KICKED);
		return false;
	}

	//リクエスト完成
	if(!init_request(&con->request,info,action_code,recv,total_size)){
		log_file = lock_log_file();
		time_output();
		ip_output(con->ip);
		fprintf(log_file,"(%s)Invalid Request.\n",info->name);
		unlock_log_file();
		//処理
		free_request(&con->request);
		disconnect_user(info);
		//KICKED
		connection_return_req_data_header(con,CONNECTION_ACTION_KICKED);
		return false;
	}
	//スイッチ
	switch_request(con);
	disconnect_user(info);
	free_request(&con->request);
	return true;
}
Beispiel #9
0
/**
 * Logout User from Database
 * @param user User Node
 */
void logout_user(SceNetAdhocctlUserNode * user)
{
	// Disconnect from Group
	if(user->group != NULL) disconnect_user(user);

	// Unlink Leftside (Beginning)
	if(user->prev == NULL) _db_user = user->next;
	
	// Unlink Leftside (Other)
	else user->prev->next = user->next;
	
	// Unlink Rightside
	if(user->next != NULL) user->next->prev = user->prev;
	
	// Close Stream
	close(user->stream);
	
	// Playing User
	if(user->game != NULL)
	{
		// Notify User
		uint8_t * ip = (uint8_t *)&user->resolver.ip;
		char safegamestr[10];
		memset(safegamestr, 0, sizeof(safegamestr));
		strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
		printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) stopped playing %s.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr);
		
		// Fix Game Player Count
		user->game->playercount--;
		
		// Empty Game Node
		if(user->game->playercount == 0)
		{
			// Unlink Leftside (Beginning)
			if(user->game->prev == NULL) _db_game = user->game->next;
			
			// Unlink Leftside (Other)
			else user->game->prev->next = user->game->next;
			
			// Unlink Rightside
			if(user->game->next != NULL) user->game->next->prev = user->game->prev;
			
			// Free Game Node Memory
			free(user->game);
		}
	}
	
	// Unidentified User
	else
	{
		// Notify User
		uint8_t * ip = (uint8_t *)&user->resolver.ip;
		printf("Dropped Connection to %u.%u.%u.%u.\n", ip[0], ip[1], ip[2], ip[3]);
	}
	
	// Free Memory
	free(user);
	
	// Fix User Counter
	_db_user_count--;
	
	// Update Status Log
	update_status();
}