示例#1
0
int32 map_cleanup(uint32 tick, CTaskMgr::CTask* PTask)
{
    map_session_list_t::iterator it = map_session_list.begin();

    while(it != map_session_list.end())
    {
        map_session_data_t* map_session_data = it->second;

        if( (time(NULL) - map_session_data->last_update) > (map_config.max_time_lastupdate/1000) )
        {
            if (map_session_data->PChar)
            {
                ShowWarning("map_cleanup: "CL_WHITE"%s"CL_RESET" timed out, session closed\n",map_session_data->PChar->GetName());

                map_session_data->PChar->status = STATUS_SHUTDOWN;
                PacketParcer[0x00D](map_session_data, map_session_data->PChar, 0);
            } else {
                ShowWarning("map_cleanup: "CL_WHITE"WHITHOUT CHAR"CL_RESET" timed out, session closed\n");

                const int8* fmtQuery = "DELETE FROM accounts_sessions WHERE client_addr = %u AND client_port = %u";
                Sql_Query(SqlHandle,fmtQuery,map_session_data->client_addr,map_session_data->client_port);

                aFree(map_session_data->server_packet_data);
                delete map_session_data;
                map_session_list.erase(it++);
                continue;
            }
        }
        ++it;
    }
    return 0;
}
示例#2
0
map_session_data_t* mapsession_getbyipp(uint64 ipp)
{
    map_session_list_t::iterator i = map_session_list.find(ipp);
    if( i == map_session_list.end() )
        return NULL;

    return (*i).second;
}
示例#3
0
文件: map.cpp 项目: Elkazan/darkstar
map_session_data_t* mapsession_getbyipp(uint64 ipp)
{
    map_session_list_t::iterator i = map_session_list.begin();
    while (i != map_session_list.end())
    {
        if ((*i).first == ipp)
            return (*i).second;
        i++;
    }
    return nullptr;
}
示例#4
0
文件: map.cpp 项目: Elkazan/darkstar
int32 map_close_session(uint32 tick, map_session_data_t* map_session_data)
{
    if (map_session_data != nullptr &&
        map_session_data->server_packet_data != nullptr &&
        map_session_data->PChar != nullptr)
    {
        charutils::SavePlayTime(map_session_data->PChar);

        //clear accounts_sessions if character is logging out (not when zoning)
        if (map_session_data->shuttingDown == 1)
        {
            Sql_Query(SqlHandle, "DELETE FROM accounts_sessions WHERE charid = %u", map_session_data->PChar->id);
        }

        uint64 port64 = map_session_data->client_port;
        uint64 ipp = map_session_data->client_addr;
        ipp |= port64 << 32;

        map_session_data->PChar->StatusEffectContainer->SaveStatusEffects(map_session_data->shuttingDown == 1);

        aFree(map_session_data->server_packet_data);
        delete map_session_data->PChar;
        delete map_session_data;
        map_session_data = nullptr;

        map_session_list.erase(ipp);
        return 0;
    }

    ShowError(CL_RED"map_close_session: cannot close session, session not found\n" CL_RESET);
    return 1;
}
示例#5
0
文件: map.cpp 项目: Gwynthell/FFDB
int32 map_close_session(uint32 tick, CTaskMgr::CTask* PTask)
{
	map_session_data_t* map_session_data = (map_session_data_t*)PTask->m_data;

	if (map_session_data != NULL &&
		map_session_data->server_packet_data != NULL &&		// bad pointer crashed here, might need dia to look at this one
		map_session_data->PChar != NULL)					// crash occured when both server_packet_data & PChar were NULL
	{
		charutils::SavePlayTime(map_session_data->PChar);

		Sql_Query(SqlHandle, "DELETE FROM accounts_sessions WHERE charid = %u", map_session_data->PChar->id);

		uint64 port64 = map_session_data->client_port;
		uint64 ipp	  = map_session_data->client_addr;
		ipp |= port64<<32;

		map_session_data->PChar->StatusEffectContainer->SaveStatusEffects();

		aFree(map_session_data->server_packet_data);
		delete map_session_data->PChar;
		delete map_session_data;
		map_session_data = NULL;

		map_session_list.erase(ipp);
		ShowDebug(CL_CYAN"map_close_session: session closed\n" CL_RESET);
		return 0;
	}

	ShowError(CL_RED"map_close_session: cannot close session, session not found\n" CL_RESET);
	return 1;
}
示例#6
0
int32 map_close_session(uint32 tick, CTaskMgr::CTask* PTask)
{
    map_session_data_t* map_session_data = (map_session_data_t*)PTask->m_data;

    if (map_session_data != NULL)
    {
        Sql_Query(SqlHandle,"DELETE FROM accounts_sessions WHERE charid = %u",map_session_data->PChar->id);

        uint64 port64 = map_session_data->client_port;
        uint64 ipp	  = map_session_data->client_addr;
        ipp |= port64<<32;

        map_session_data->PChar->StatusEffectContainer->SaveStatusEffects();

        aFree(map_session_data->server_packet_data);
        delete map_session_data->PChar;
        delete map_session_data;

        map_session_list.erase(ipp);
        ShowDebug(CL_CYAN"map_close_session: session closed\n"CL_RESET);
        return 0;
    }

    ShowError(CL_RED"map_close_session: cannot close session, session not found\n"CL_RESET);
    return 1;
}
示例#7
0
文件: map.cpp 项目: Elkazan/darkstar
int32 map_cleanup(uint32 tick, CTaskMgr::CTask* PTask)
{
    map_session_list_t::iterator it = map_session_list.begin();

    while (it != map_session_list.end())
    {
        map_session_data_t* map_session_data = it->second;

        CCharEntity* PChar = map_session_data->PChar;

        if ((time(nullptr) - map_session_data->last_update) > 5)
        {
            if (PChar != nullptr && !(PChar->nameflags.flags & FLAG_DC))
            {

                PChar->nameflags.flags |= FLAG_DC;
                PChar->updatemask |= UPDATE_HP;
                if (PChar->status == STATUS_NORMAL)
                {
                    PChar->loc.zone->SpawnPCs(PChar);
                }
            }
            if ((time(nullptr) - map_session_data->last_update) > map_config.max_time_lastupdate)
            {
                if (PChar != nullptr)
                {
                    if (map_session_data->shuttingDown == 0)
                    {
                        //[Alliance] fix to stop server crashing:
                        //if a party within an alliance only has 1 char (that char will be party leader)
                        //if char then disconnects we need to tell the server about the alliance change
                        if (PChar->PParty != nullptr && PChar->PParty->m_PAlliance != nullptr && PChar->PParty->GetLeader() == PChar)
                        {
                            if (PChar->PParty->members.size() == 1)
                            {
                                if (PChar->PParty->m_PAlliance->partyList.size() == 1)
                                {
                                    PChar->PParty->m_PAlliance->dissolveAlliance();
                                }
                                else
                                {
                                    PChar->PParty->m_PAlliance->removeParty(PChar->PParty);
                                }
                            }
                        }


                        // uncharm pet if player d/c
                        if (PChar->PPet != nullptr && PChar->PPet->objtype == TYPE_MOB)
                        {
                            petutils::DespawnPet(PChar);
                        }

                        PChar->StatusEffectContainer->SaveStatusEffects(true);
                        ShowDebug(CL_CYAN"map_cleanup: %s timed out, closing session\n" CL_RESET, PChar->GetName());

                        PChar->status = STATUS_SHUTDOWN;
                        PacketParser[0x00D](map_session_data, PChar, 0);
                    }
                    else
                    {
                        map_session_data->PChar->StatusEffectContainer->SaveStatusEffects(true);
                        Sql_Query(SqlHandle, "DELETE FROM accounts_sessions WHERE charid = %u;", map_session_data->PChar->id);

                        aFree(map_session_data->server_packet_data);
                        delete map_session_data->PChar;
                        delete map_session_data;
                        map_session_data = nullptr;

                        map_session_list.erase(it++);
                        continue;
                    }
                }
                else if (map_session_data->shuttingDown == 0)
                {

                    ShowWarning(CL_YELLOW"map_cleanup: WHITHOUT CHAR timed out, session closed\n" CL_RESET);

                    const int8* Query = "DELETE FROM accounts_sessions WHERE client_addr = %u AND client_port = %u";
                    Sql_Query(SqlHandle, Query, map_session_data->client_addr, map_session_data->client_port);

                    aFree(map_session_data->server_packet_data);
                    map_session_list.erase(it++);
                    delete map_session_data;
                    continue;
                }
            }
        }
        else if (PChar != nullptr && (PChar->nameflags.flags & FLAG_DC))
        {
            PChar->nameflags.flags &= ~FLAG_DC;
            PChar->updatemask |= UPDATE_HP;
            PChar->pushPacket(new CCharUpdatePacket(PChar));

            if (PChar->status == STATUS_NORMAL)
            {
                PChar->loc.zone->SpawnPCs(PChar);
            }
            charutils::SaveCharStats(PChar);
        }
        ++it;
    }
    return 0;
}
示例#8
0
文件: map.cpp 项目: Elkazan/darkstar
int32 do_sockets(fd_set* rfd, int32 next)
{
    struct timeval timeout;
    int32 ret;
    memcpy(rfd, &readfds, sizeof(*rfd));

    timeout.tv_sec = next / 1000;
    timeout.tv_usec = next % 1000 * 1000;

    ret = sSelect(fd_max, rfd, nullptr, nullptr, &timeout);

    if (ret == SOCKET_ERROR)
    {
        if (sErrno != S_EINTR)
        {
            ShowFatalError("do_sockets: select() failed, error code %d!\n", sErrno);
            do_final(EXIT_FAILURE);
        }
        return 0; // interrupted by a signal, just loop and try again
    }

    last_tick = time(nullptr);

    if (sFD_ISSET(map_fd, rfd))
    {
        struct sockaddr_in from;
        socklen_t fromlen = sizeof(from);

        int32 ret = recvudp(map_fd, g_PBuff, map_config.buffer_size, 0, (struct sockaddr*)&from, &fromlen);
        if (ret != -1)
        {
            // find player char
#   ifdef WIN32
            uint32 ip = ntohl(from.sin_addr.S_un.S_addr);
#   else
            uint32 ip = ntohl(from.sin_addr.s_addr);
#   endif

            uint64 port = ntohs(from.sin_port);
            uint64 ipp = ip;
            ipp |= port << 32;
            map_session_data_t* map_session_data = mapsession_getbyipp(ipp);

            if (map_session_data == nullptr)
            {
                map_session_data = mapsession_createsession(ip, ntohs(from.sin_port));
                if (map_session_data == nullptr)
                {
					map_session_list.erase(ipp);
                    return -1;
                }
            }

            map_session_data->last_update = time(nullptr);
            size_t size = ret;

            if (recv_parse(g_PBuff, &size, &from, map_session_data) != -1)
            {
                // если предыдущий пакет был потерян, то мы не собираем новый,
                // а отправляем предыдущий пакет повторно
                if (!parse(g_PBuff, &size, &from, map_session_data))
                {
                    send_parse(g_PBuff, &size, &from, map_session_data);
                }

                ret = sendudp(map_fd, g_PBuff, size, 0, (const struct sockaddr*)&from, fromlen);

                int8* data = g_PBuff;
                g_PBuff = map_session_data->server_packet_data;

                map_session_data->server_packet_data = data;
                map_session_data->server_packet_size = size;
            }
            if (map_session_data->shuttingDown > 0)
            {
                map_close_session(gettick(), map_session_data);
            }
        }
    }
    return 0;
}