Beispiel #1
0
void spawn_tile_collision (Spawn *self, Tile *tile, Map *map) {
    /* Kartenrand / unbegehbar */
    if(self->x >= map->x || self->y >= map->y || !tile_can_walk(*tile)) {
        /* umkehren */
        switch(self->direction) {
            case NORTH:
                self->y++;
                break;
            case SOUTH:
                self->y--;
                break;
            case EAST:
                self->x--;
                break;
            case WEST:
                self->x++;
                break;
        }
        if (tile->type == TILE_TYPE_WALL) {
            damage_spawn(self, 1, map);
            push_msg("Kopf -> Wand (-1HP)", map);
        }
    }
    else {
        if (tile->number_of_items > 0) {
            /* Items aufsammeln. */
            self->inventory = ex_realloc(self->inventory, (self->inventory_size + tile->number_of_items) * sizeof(Item*));
            for (unsigned int ii = 0; ii < tile->number_of_items; ++ii) {
                if(tile->items[ii]->type != ITEM_TYPE_INVALID) {
                    self->inventory[++self->inventory_size - 1] = tile->items[ii];
                }
            }
            /* Aufzählen, was aufgesammelt */
            for(unsigned int i = 0; i < tile->number_of_items; ++i) {
                if(tile->items[i]->type != ITEM_TYPE_INVALID) {
                    char* item_message = (char*)ex_calloc(22 + strlen(tile->items[i]->name), 1);                
                    sprintf(item_message, "Du hast aufgenommen: %s", tile->items[i]->name);
                    push_msg(item_message, map);
                    free(item_message);
                }
            }
            self->selected_item=self->inventory_size-1;
            
            free(tile->items);
            tile->items = NULL;
            tile->number_of_items = 0;
        } 
        /* Ausgang */
        else if(tile->type == TILE_TYPE_EXIT) {
            map->finished = 1;
        }
    }
}
Beispiel #2
0
void QQ::pre_sign_in_step_2()
{
	size_t req_size = 13;

	uint8_t* request = new_request(0x62, req_size);
	push_msg(request, req_size);
	delete[] request;

	set_state(QQ_WF_LOGINTOKEN);
}
Beispiel #3
0
void spawn_spawn_collision (Spawn *self, Spawn *other, Map *map) {
    switch(self->type){
    case SPAWN_TYPE_PLAYER:
        switch(other->type){
        case SPAWN_TYPE_HOUND:
            damage_spawn(other, 10, map);
            break;
        case SPAWN_TYPE_ZOMBIE:
            damage_spawn(other, 10, map);
            break;
        default:
            break;
        }
        break;
    case SPAWN_TYPE_HOUND:
        switch(other->type){
        case SPAWN_TYPE_PLAYER:
            damage_spawn(other, 5, map);
            push_msg("gebissen! (-5HP)", map);
            break;
        default:
            break;
        }
        break;
    case SPAWN_TYPE_ZOMBIE:
        switch(other->type){
        case SPAWN_TYPE_PLAYER:
            damage_spawn(other, 10, map);
            push_msg("Baem! (-10HP)", map);
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }
}
Beispiel #4
0
void QQ::dispatch_msg()
{	
	uint8_t msg[messenger::BUF_SIZE] = {0};

	int len = 0;
	int i = 0;
	size_t j = 0;

	bool match = false;
	char msg_info[128] = {0};
	uint8_t* compare = NULL;
	size_t count = 0;

	qq_state_enum state = get_state();

	if (msgr == NULL || msgr->get_incoming_msg_queue_size() == 0)
	{
		return;
	}

	pthread_mutex_lock(&srv_ip_mtx);

	switch (state)
	{
	case QQ_WF_PREFIRST:
	case QQ_WF_REDIRECT:
		if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0)
		{		
			break;
		}
		
		if (len < 10)
		{
			break;
		}

		// count = hex_string_to_bytes("02030000310004010003" , &compare);
		count = hex_string_to_bytes("02000000310004010003" , &compare); //2009-08-06		
		
		if (memcmp((char*)msg, compare, count) == 0)
		{
			delay(200);
			set_state(QQ_LOGINTOKEN);
		}

		delete[] compare;
		break;		

	case QQ_WF_LOGINTOKEN:
		if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0)
		{		
			cout << "Read NONE!" << endl;
			break;
		}

		if (len >= 34)
		{
			// 请求登录令牌的命令号 0x0062
			count = hex_string_to_bytes("020e35006200000018", &compare); 
			match = true;

			for (j = 0; j < count; j++)
			{
				if (j == 5 || j == 6)
					continue;
				if (msg[j] != compare[j])
				{
					match = false;
					break;
				}
			}

			delete[] compare;
		}
		if (match)
		{
			pthread_mutex_lock(&login_token_mtx);
			for (j = 0; j < 24; j++)
				login_token[j] = msg[j + 9];	
			pthread_mutex_unlock(&login_token_mtx);
			delay(200);
			set_state(QQ_LOGIN_IN);
		}
		break;

	case QQ_WF_LOGIN_IN:
		{
			if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0)
			{		
				break;
			}
			
			if (len < 32)
			{
				printf("QQ_WF_LOGIN_IN: len == %d < 32, break.\n", len);
				break;
			}
			count = hex_string_to_bytes("020e350022", &compare);

			if (memcmp((char*)msg, compare, count) != 0)
			{
				delete[] compare; 
				break;
			}
			delete[] compare; 			

			if (len == 32)
			{
				delay(200);
				set_state(QQ_REDIRECT);
				//cout << "QQ_REDIRECT" << endl;
				pthread_mutex_lock(&rand_key_mtx);
				TEA tea(rand_key);
				pthread_mutex_unlock(&rand_key_mtx);

				unsigned char * plain_msg = NULL;
				if (tea.qq_decrypt((msg + 7), 24, &plain_msg) != 11)
				{
					cout << "Decrypt Failed!" << endl;
					delay(200);
					set_state(QQ_ZERO);
					break;
				}
				unsigned int   n_ip = *((unsigned int *) (plain_msg + 5));
				unsigned short n_port = *((unsigned short *) (plain_msg + 9));
				unsigned short h_port = ntohs(n_port);
				unsigned int h_ip = ntohl(n_ip);

				memset(srv_ip, 0, IPADDR_LEN);
				sprintf(srv_ip, "%d.%d.%d.%d", 
					(h_ip >> 24) % 0x100,
					(h_ip >> 16) % 0x100, 
					(h_ip >> 8) % 0x100,
					h_ip % 0x100);

				srv_port = h_port;
				delete[] plain_msg;
				break;
			}

			if (len == 88)
			{
				printf("QQ_WF_LOGIN_IN: recieved 88 bytes.\n");	
			}

			if (len != 192)
			{
				printf("QQ_WF_LOGIN_IN: len == %d != 192, login failed, try again.\n", len);
				set_state(QQ_ZERO);
				break;
			}

			uint8_t * pwhash2 = NULL;
			hex_string_to_bytes(qq_pw, &pwhash2);		

			TEA tea(pwhash2);
			uint8_t * plain_msg = NULL;

			try
			{
				tea.qq_decrypt((msg + 7), 184, &plain_msg);
			}
			catch (out_of_range e)
			{
				cout << e.what() << endl;
			}

			uint32_t my_qq_id = 0;
			uint32_t my_ip = 0;
			uint16_t my_port = 0;
			uint32_t srv_listen_ip = 0;
			uint16_t srv_listen_port = 0;
			time_t login_time = 0;
			struct tm* tm_ptr;
			uint32_t unknown_ip = 0;

			switch (plain_msg[0])
			{
			case 0x00:
				memcpy(session_key, plain_msg + 1, 16);				
				delay(200);
				set_state(QQ_PRE_ONLINE_FIR);

				my_qq_id = ntohl(*((uint32_t *) (plain_msg + 17)));
				my_ip = ntohl(*((uint32_t *) (plain_msg + 21)));
				my_port = ntohs(*((uint16_t *) (plain_msg + 25)));
				srv_listen_ip = ntohl(*((uint32_t *) (plain_msg + 27)));
				srv_listen_port = ntohs(*((uint16_t *) (plain_msg + 31)));
				login_time = (time_t)
					ntohl(*((uint32_t *) (plain_msg + 33)));
				unknown_ip = ntohl(*((uint32_t *) (plain_msg + 63)));

				tm_ptr = localtime(&login_time);					

				sprintf(client_ip_port, "%d.%d.%d.%d:%d",
					(my_ip >> 24) % 0x100, (my_ip >> 16) % 0x100,
					(my_ip >> 8) % 0x100, my_ip % 0x100, my_port);		

				sprintf(signin_time, "%02d:%02d:%02d", tm_ptr->tm_hour,
					tm_ptr->tm_min, tm_ptr->tm_sec);

				sprintf(msg_info, "QQ ID:\t%d\r\nIP Addr:\t%s\r\nTime:\t\t%s",
					my_qq_id, client_ip_port, signin_time);
				log_event(msg_info);

				break;

			default:
				delay(200);
				set_state(QQ_ZERO);
				break;
			}

			delete[] plain_msg;	
			delete[] pwhash2;

			break;
		}

	case QQ_WF_PRE_ONLINE_FIR:
		{
			if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0)
			{		
				break;
			}

			cout << "Server IP:\t" << srv_ip << ":" << srv_port << endl;

			if (msg[0] == 0x02 &&
				msg[1] == 0x0e &&
				msg[2] == 0x35)
			{
				TEA tea(session_key);
				unsigned char * plain_msg = NULL;
				tea.qq_decrypt((msg + 7), len - 8, &plain_msg);
				unsigned short order = msg[3] * 0x100 + msg[4];

				switch (order)
				{
				case 0x6:
					{
						my_profile_gotten = true;
						set_state(QQ_PRE_ONLINE_SEC);
						break;
					}
				}

				delete[] plain_msg;
			}

			break;
		}

	case QQ_WF_PRE_ONLINE_SEC:
		{
			if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0)
			{		
				break;
			}

			if (msg[0] == 0x02 &&
				msg[1] == 0x0e &&
				msg[2] == 0x35)
			{
				TEA tea(session_key);
				unsigned char * plain_msg = NULL;
				int msg_len = tea.qq_decrypt((msg + 7), len - 8,
					&plain_msg);
				unsigned short order = msg[3] * 0x100 + msg[4];

				switch (order)
				{
				case 0x26:
					{
						memcpy(friend_id, plain_msg, 2);

						if (plain_msg[0] * 0x100 + plain_msg[1] == 0xffff)
						{
							set_state(QQ_ONLINE);							
							delay(200);
						}
						else
						{
							delay(200);
							set_state(QQ_PRE_ONLINE_SEC);
						}

						i = 2;

						while (i < msg_len)
						{
							int* pint = (int*) (plain_msg + i);
							int buddy_id = ntohl(*pint);
							unsigned char ssize = *(plain_msg + i + 8);
							char* nickname = new char[ssize + 1];
							memset(nickname, 0, ssize + 1);
							memcpy(nickname, plain_msg + i + 9, ssize);
							char ss[20];
							sprintf(ss, "<%d>", buddy_id);
							char* listchars = new char[ssize + 1 + 20];
							strcpy(listchars, nickname);
							strcat(listchars, ss);

							string buddy_nickname = nickname;
							contact.insert(pair<int, string>(buddy_id,
								buddy_nickname));

							delete[] nickname;
							delete[] listchars;
							i = i + 9 + ssize + 4;
						}

						break;
					}
				}

				delete[] plain_msg;
			}

			break;
		}

	case QQ_ONLINE:
		{
			if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0)
			{		
				break;
			}
			if (msg[0] == 0x02)
			{
				TEA tea(session_key);
				unsigned char * plain_msg = NULL;
				int msg_len = tea.qq_decrypt((msg + 7), len - 8,
					&plain_msg);

				unsigned short order = msg[3] * 0x100 + msg[4];
				char signature[128];

				switch (order)
				{
				case 0x02:
					pthread_mutex_lock(&drop_flag_mtx);
					drop_flag = 0;
					pthread_mutex_unlock(&drop_flag_mtx);
					break;
	
				case 0x17:
					{
						int sender_qq = ntohl(*((int*) plain_msg));      //发送者QQ号	
						int mlong = msg_len - 65 - plain_msg[msg_len - 1];

						if (mlong > 0)
						{
							char* received_msg = new char[mlong + 1];
							memset(received_msg, 0, mlong + 1);
							memcpy(received_msg, plain_msg + 65, mlong);

							if (config.set_received_msg_as_personal_msg)
							{
								strncpy((char *) signature, received_msg, 100);
								set_personal_msg((const char *) signature);
							}

							process_msg(sender_qq, received_msg);

							delete[] received_msg;
							/*
							 * 回复 收到了消息
							 * 1. 消息发送者QQ号,4字节
							 * 2. 消息接收者QQ号,4字节,也就是我
							 * 3. 消息序号,4字节
							 * 4. 发送者IP,4字节
							 */
							unsigned char * plaintext = new unsigned char[16];
							memcpy(plaintext, plain_msg, 16);
							unsigned char * ciphertext = NULL;
			
							size_t miSize = tea.qq_encrypt(plaintext, 16,
								&ciphertext);

							size_t msg_size = miSize + 12;

							uint8_t* request = new_request(0x17, msg_size);

							request[5] = msg[5]; // TEA::Rand();
							request[6] = msg[6]; // TEA::Rand();
							memcpy(request + 11, ciphertext, miSize);

							push_msg(request, msg_size, false);
				
							delete[] plaintext;
							delete[] ciphertext;
							delete[] request;
						}
						break;
					}
				}
				delete [] plain_msg;
			}

			break;
		}

	default:
		break;
	}
Beispiel #5
0
void toggle_tile (Tile *self, Map *map) {
    /* Button */
    if(self->type == TILE_TYPE_BUTTON) {    
        ButtonProperties* btn_props = (ButtonProperties*)self->properties;
        if(btn_props->toggle_id == NULL) {
            return;
        }
        unsigned int map_size = map->x * map->y;
        Tile* to_toggle;
        for (unsigned int ii = 0; ii < map_size; ++ii) {
            to_toggle = &map->tiles[ii];
            if(to_toggle->id == NULL || to_toggle == self) {
                continue;
            }
            if (0 == strcmp(btn_props->toggle_id, to_toggle->id)) {
                /* Sonderbehandlung Tür, wenn durch externen Button gedrückt */
                if(to_toggle->type == TILE_TYPE_DOOR) {
                    DoorProperties* door_props = (DoorProperties *)to_toggle->properties;
                    /* hat externen Schalter, wird also hier getoggelt */
                    if(door_props->external_button) {
                        door_props->open ^= 1;
                    } 
                    /* sonst entscheidet der Schalter nur über Verriegelung */
                    else {
                        door_props->locked ^= 1;
                    }
                }
                /* Wand */
                else if(to_toggle->type == TILE_TYPE_WALL)  {
                    WallProperties* wall_props = (WallProperties *)to_toggle->properties;
                    wall_props->floor ^= 1;
                }
                else {
                    toggle_tile(to_toggle, map);
                }
                break;
            }
        }
    }
    /* Tür */
    else if(self->type == TILE_TYPE_DOOR)  {
        DoorProperties* door_props = (DoorProperties *)self->properties;
        /* Tür hat eigenen Schalter und ist nicht verschlossen */
        if(!door_props->locked) {
            if(!(door_props->external_button)) {
                door_props->open ^= 1;
            }
        } else {
            /* Mit Schlüssel aufschließbar */
            if(door_props->key_id != NULL) {
                unsigned int i;
                Spawn* player = get_player_spawn(map);
                /* Inventar scannen */
                for(i = 0; i < player->inventory_size; ++i) {
                    Item* key_candidate = player->inventory[i];
                    if(key_candidate != NULL && key_candidate->type == ITEM_TYPE_KEY) {
                        if(strcmp(key_candidate->id, door_props->key_id) == 0) {
                            /* Key entfernen! */
                            delete_item(key_candidate, player);
                            door_props->locked = 0;
                            push_msg("Tuer entriegelt", map);
                            break;
                        }
                    }
                }
                /* wurde nicht aufgemacht */
                if(door_props->locked) {
                    push_msg("Tuer verschlossen", map);
                }
            }
        }
    }
    /* Hinweis */
    else if(self->type == TILE_TYPE_HINT)  {
        HintProperties* hint_props = (HintProperties *)self->properties;
        if(hint_props->message != NULL) {
            /* Was das Ding zu sagen hat, in den Ausgabestream packen! */
            push_msg(hint_props->message, map);
        }
    }
}
Beispiel #6
0
void spawn_uses_item (Spawn *self, Item *item, Map *map) {
    (void)map;
    switch (item->type) {
    case ITEM_TYPE_HEALTH_POTION:
        self->hp += ((HealthPotionProperties *)item->properties)->capacity;
        if (self->hp > self->max_hp) {
            self->hp = self->max_hp;
        }
        push_msg("Schluck! (Heiltrank)", map);
        /* raus mit dem Item ... */
        delete_item(item, self);
        break;
    case ITEM_TYPE_DEAD_CAT:
        push_msg("Miau?", map);
        break;
	case ITEM_TYPE_SHOTGUN:
	    /*Schaden anrichten, wenn noch Muni da war*/
	    if(delete_item_by_type(ITEM_TYPE_SHOTGUN_AMMO, self)){
	        Spawn *victim=NULL;
            unsigned int damage=0;
            switch(self->direction){
            case NORTH:
		        for(unsigned int i=1;i<=10 && self->y-i+1;i++){
                    /*wenn da ne Wand ist, nichts tun*/
                    if(!tile_can_walk(map->tiles[map->x*(self->y-i)+self->x]))
                        break;
		            victim=get_spawn_at(self->x, self->y-i, map);
                    if(victim!=NULL){
                        /*weniger bei mehr Entfernung*/
                        damage=(11-i)*3;
                        break;
                    }
                }
	        	break;
             case SOUTH:
		        for(unsigned int i=1;i<=10 && self->y+i<map->y;i++){
                    /*wenn da ne Wand ist, nichts tun*/
                    if(!tile_can_walk(map->tiles[map->x*(self->y+i)+self->x]))
                        break;
		            victim=get_spawn_at(self->x, self->y+i, map);
                    if(victim!=NULL){
                        damage=(11-i)*3;
                        break;
                    }
                }
	        	break;
             case WEST:
		        for(unsigned int i=1;i<=10 && self->x-i+1;i++){
                    /*wenn da ne Wand ist, nichts tun*/
                    if(!tile_can_walk(map->tiles[map->x*self->y+self->x-i]))
                        break;
		            victim=get_spawn_at(self->x-i, self->y, map);
                    if(victim!=NULL){
                        damage=(11-i)*3;
                        break;
                    }
                }
	        	break;
             case EAST:
		        for(unsigned int i=1;i<=10 && self->x+i<map->x;i++){
                    /*wenn da ne Wand ist, nichts tun*/
                    if(!tile_can_walk(map->tiles[map->x*self->y+self->x+i]))
                        break;
		            victim=get_spawn_at(self->x+i, self->y, map);
                    if(victim!=NULL){
                        damage=(11-i)*3;
                        break;
                    }
                }
	        	break;
         default:
                break;
            }
            if(victim!=NULL)
                damage_spawn(victim, damage, map);
        }
        else
            push_msg("Keine Munition mehr!", map);
	    break;
    default:
        break;
    }
}