Fix a crash in packet_split. Packets don't always arrive full.
This commit is contained in:
parent
a870dc618f
commit
09e585b549
@ -18,7 +18,7 @@
|
||||
|
||||
-module(egs_game).
|
||||
-export([start/0]). % external
|
||||
-export([listen/0, accept/1, process/2, char_select/3, lobby_load/4, loop/3]). % internal
|
||||
-export([listen/0, accept/1, process/2, char_select/3, lobby_load/4, loop/3, loop/4]). % internal
|
||||
|
||||
-include("include/records.hrl").
|
||||
-include("include/network.hrl").
|
||||
@ -215,11 +215,16 @@ lobby_load(CSocket, GID, Map, Entry) ->
|
||||
log(GID, "send error, closing")
|
||||
end.
|
||||
|
||||
%% @doc Alias for the game main's loop when the buffer is empty.
|
||||
|
||||
loop(CSocket, GID, Version) ->
|
||||
loop(CSocket, GID, Version, << >>).
|
||||
|
||||
%% @doc Game's main loop.
|
||||
%% @todo Have some kind of clock process for keepalive packets.
|
||||
%% @todo Handle 0102 and 0503 broadcasts correctly.
|
||||
|
||||
loop(CSocket, GID, Version) ->
|
||||
loop(CSocket, GID, Version, SoFar) ->
|
||||
receive
|
||||
{psu_broadcast_0102, Data} ->
|
||||
<< _:96, SrcGID:32/little-unsigned-integer, _:256, After/bits >> = Data,
|
||||
@ -234,7 +239,7 @@ loop(CSocket, GID, Version) ->
|
||||
LID:32/little-unsigned-integer, After/binary >>,
|
||||
egs_proto:packet_send(CSocket, Send)
|
||||
end,
|
||||
?MODULE:loop(CSocket, GID, Version);
|
||||
?MODULE:loop(CSocket, GID, Version, SoFar);
|
||||
{psu_broadcast_010f, Data} ->
|
||||
<< _:96, SrcGID:32/little-unsigned-integer, _:256, After/bits >> = Data,
|
||||
% TODO: assign the LID correctly when sending the character info for the player's character, not when broadcasting
|
||||
@ -248,7 +253,7 @@ loop(CSocket, GID, Version) ->
|
||||
LID:32/little-unsigned-integer, After/binary >>,
|
||||
egs_proto:packet_send(CSocket, Send)
|
||||
end,
|
||||
?MODULE:loop(CSocket, GID, Version);
|
||||
?MODULE:loop(CSocket, GID, Version, SoFar);
|
||||
{psu_broadcast_0503, Data} ->
|
||||
<< _:96, SrcGID:32/little-unsigned-integer, _:256, After/bits >> = Data,
|
||||
% TODO: assign the LID correctly when sending the character info for the player's character, not when broadcasting
|
||||
@ -262,17 +267,17 @@ loop(CSocket, GID, Version) ->
|
||||
LID:32/little-unsigned-integer, After/binary >>,
|
||||
egs_proto:packet_send(CSocket, Send)
|
||||
end,
|
||||
?MODULE:loop(CSocket, GID, Version);
|
||||
?MODULE:loop(CSocket, GID, Version, SoFar);
|
||||
{psu_chat, ChatGID, ChatName, ChatModifiers, ChatMessage} ->
|
||||
egs_proto:send_chat(CSocket, Version, ChatGID, ChatName, ChatModifiers, ChatMessage),
|
||||
?MODULE:loop(CSocket, GID, Version);
|
||||
?MODULE:loop(CSocket, GID, Version, SoFar);
|
||||
{psu_player_spawn, SpawnPlayer} ->
|
||||
send_spawn(CSocket, GID, SpawnPlayer),
|
||||
?MODULE:loop(CSocket, GID, Version);
|
||||
?MODULE:loop(CSocket, GID, Version, SoFar);
|
||||
{ssl, _, Data} ->
|
||||
Packets = egs_proto:packet_split(Data),
|
||||
{Packets, Rest} = egs_proto:packet_split(<< SoFar/bits, Data/bits >>),
|
||||
[dispatch(CSocket, GID, Version, P) || P <- Packets],
|
||||
?MODULE:loop(CSocket, GID, Version);
|
||||
?MODULE:loop(CSocket, GID, Version, Rest);
|
||||
{ssl_closed, _} ->
|
||||
log(GID, "ssl closed~n"),
|
||||
egs_db:users_delete(GID),
|
||||
@ -282,11 +287,11 @@ loop(CSocket, GID, Version) ->
|
||||
egs_db:users_delete(GID),
|
||||
ssl:close(CSocket);
|
||||
_ ->
|
||||
?MODULE:loop(CSocket, GID, Version)
|
||||
?MODULE:loop(CSocket, GID, Version, SoFar)
|
||||
after 1000 ->
|
||||
egs_proto:send_keepalive(CSocket, GID),
|
||||
reload,
|
||||
?MODULE:loop(CSocket, GID, Version)
|
||||
?MODULE:loop(CSocket, GID, Version, SoFar)
|
||||
end.
|
||||
|
||||
%% @doc Dispatch the command to the right handler.
|
||||
|
@ -101,14 +101,22 @@ packet_fragment_send(CSocket, Packet, Size, Current) ->
|
||||
%% @doc Split a packet received into commands. This is only needed when receiving packets in active mode.
|
||||
|
||||
packet_split(Packet) ->
|
||||
packet_split(Packet, []).
|
||||
|
||||
packet_split(Packet, Result) ->
|
||||
<< Size:32/little-unsigned-integer, _/bits >> = Packet,
|
||||
BitSize = Size * 8,
|
||||
<< Split:BitSize/bits, Rest/bits >> = Packet,
|
||||
case Rest of
|
||||
<< >> ->
|
||||
[ Split ];
|
||||
_ ->
|
||||
[ Split | packet_split(Rest) ]
|
||||
case Size > byte_size(Packet) of
|
||||
true ->
|
||||
{Result, Packet};
|
||||
false ->
|
||||
BitSize = Size * 8,
|
||||
<< Split:BitSize/bits, Rest/bits >> = Packet,
|
||||
case Rest of
|
||||
<< >> ->
|
||||
{Result ++ [Split], << >>};
|
||||
_ ->
|
||||
packet_split(Rest, Result ++ [Split])
|
||||
end
|
||||
end.
|
||||
|
||||
%% @doc Parse a login authentication command. Return the username and password.
|
||||
|
Loading…
Reference in New Issue
Block a user