From 7ac9776f3007e5f35c2858b557c6dc087cf6b47f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 28 Jun 2010 01:33:31 +0200 Subject: [PATCH] game: Add CSocket, GID and Version into the process dictionary. --- src/egs_game.erl | 964 +++++++++++++++++++++++------------------------ 1 file changed, 482 insertions(+), 482 deletions(-) diff --git a/src/egs_game.erl b/src/egs_game.erl index 234cf16..633ab9f 100644 --- a/src/egs_game.erl +++ b/src/egs_game.erl @@ -18,7 +18,7 @@ -module(egs_game). -export([start/0]). % external --export([supervisor_init/0, supervisor/0, listen/1, accept/2, process/2, char_select/3, area_load/6, loop/3, loop/4]). % internal +-export([supervisor_init/0, supervisor/0, listen/1, accept/2, process_init/1, process/0, char_select/0, area_load/4, loop/1]). % internal -include("include/records.hrl"). -include("include/network.hrl"). @@ -77,8 +77,7 @@ accept(LSocket, SPid) -> {ok, CSocket} -> ssl:ssl_accept(CSocket), try - send_0202(CSocket), - Pid = spawn(?MODULE, process, [CSocket, 0]), + Pid = spawn(?MODULE, process_init, [CSocket]), SPid ! {link, Pid}, ssl:controlling_process(CSocket, Pid) catch @@ -90,123 +89,129 @@ accept(LSocket, SPid) -> end, ?MODULE:accept(LSocket, SPid). +%% @doc Initialize the client process by saving the socket to the process dictionary. + +process_init(CSocket) -> + put(socket, CSocket), + send_0202(), + process(). + %% @doc Process the new connections. %% Send an hello packet, authenticate the user and send him to character select. -process(CSocket, Version) -> - case egs_proto:packet_recv(CSocket, 5000) of +process() -> + case egs_proto:packet_recv(get(socket), 5000) of {ok, Orig} -> {command, Command, _, Data} = egs_proto:packet_parse(Orig), - process_handle(Command, CSocket, Version, Data); + process_handle(Command, Data); {error, timeout} -> reload, - ?MODULE:process(CSocket, Version); + ?MODULE:process(); {error, closed} -> closed end. -%% @doc Game server auth request handler. +%% @doc Game server auth request handler. Save the GID in the process dictionary after checking it. -process_handle(16#020d, CSocket, Version, << GID:32/little-unsigned-integer, Auth:32/bits, _/bits >>) -> +process_handle(16#020d, << GID:32/little-unsigned-integer, Auth:32/bits, _/bits >>) -> + CSocket = get(socket), case egs_db:users_select(GID) of error -> - log(GID, "can't find user, closing"), + log("can't find user, closing"), ssl:close(CSocket); User -> case User#users.auth of Auth -> - log(GID, "auth success"), + log("auth success"), LID = 1 + egs_db:next(lobby) rem 1023, Time = calendar:datetime_to_gregorian_seconds(calendar:universal_time()), egs_db:users_insert(#users{gid=GID, pid=self(), socket=CSocket, auth=success, time=Time, folder=User#users.folder, lid=LID}), - send_0d05(CSocket, GID), - ?MODULE:char_select(CSocket, GID, Version); + put(gid, GID), + send_0d05(), + ?MODULE:char_select(); _ -> - log(GID, "quit, auth failed"), + log("quit, auth failed"), egs_db:users_delete(GID), ssl:close(CSocket) end end; -%% @doc Platform information handler. Obtain the game version. +%% @doc Platform information handler. Obtain the game version and save it into the process dictionary. -process_handle(16#080e, CSocket, _, << _:64, Version:32/little-unsigned-integer, _/bits >>) -> - ?MODULE:process(CSocket, Version); +process_handle(16#080e, << _:64, Version:32/little-unsigned-integer, _/bits >>) -> + put(version, Version), + ?MODULE:process(); %% @doc Unknown command handler. Do nothing. -process_handle(Command, CSocket, Version, _) -> - log(0, "(process) dismissed packet ~4.16.0b", [Command]), - ?MODULE:process(CSocket, Version). +process_handle(Command, _) -> + log("(process) dismissed packet ~4.16.0b", [Command]), + ?MODULE:process(). %% @doc Character selection screen loop. %% The default entry point currently is first floor, near the uni cube. -char_select(CSocket, GID, Version) -> - case egs_proto:packet_recv(CSocket, 5000) of +char_select() -> + case egs_proto:packet_recv(get(socket), 5000) of {ok, Orig} -> {command, Command, _, Data} = egs_proto:packet_parse(Orig), - char_select_handle(Command, CSocket, GID, Version, Data); + char_select_handle(Command, Data); {error, timeout} -> - egs_proto:send_keepalive(CSocket), + egs_proto:send_keepalive(get(socket)), reload, - ?MODULE:char_select(CSocket, GID, Version); + ?MODULE:char_select(); {error, closed} -> - log(GID, "quit"), - egs_db:users_delete(GID) + log("quit"), + egs_db:users_delete(get(gid)) end. %% @doc Character selection handler. -char_select_handle(16#020b, CSocket, GID, Version, << Number:32/little-unsigned-integer, _/bits >>) -> - log(GID, "selected character ~b", [Number]), - char_select_load(CSocket, GID, Version, Number); +char_select_handle(16#020b, << Number:32/little-unsigned-integer, _/bits >>) -> + log("selected character ~b", [Number]), + char_select_load(Number); %% @doc Character creation handler. -char_select_handle(16#0d02, CSocket, GID, Version, << Number:32/little-unsigned-integer, Char/bits >>) -> - log(GID, "character creation"), - User = egs_db:users_select(GID), +char_select_handle(16#0d02, << Number:32/little-unsigned-integer, Char/bits >>) -> + log("character creation"), + User = egs_db:users_select(get(gid)), _ = file:make_dir(io_lib:format("save/~s", [User#users.folder])), file:write_file(io_lib:format("save/~s/~b-character", [User#users.folder, Number]), Char), file:write_file(io_lib:format("save/~s/~b-character.options", [User#users.folder, Number]), << 0:192 >>), - char_select_load(CSocket, GID, Version, Number); + char_select_load(Number); %% @doc Character selection screen request. -char_select_handle(16#0d06, CSocket, GID, Version, _) -> - User = egs_db:users_select(GID), - send_0d03(CSocket, GID, - data_load(User#users.folder, 0), - data_load(User#users.folder, 1), - data_load(User#users.folder, 2), - data_load(User#users.folder, 3)), - ?MODULE:char_select(CSocket, GID, Version); +char_select_handle(16#0d06, _) -> + User = egs_db:users_select(get(gid)), + send_0d03(data_load(User#users.folder, 0), data_load(User#users.folder, 1), data_load(User#users.folder, 2), data_load(User#users.folder, 3)), + ?MODULE:char_select(); %% @doc Silently ignore packet 0818. Gives CPU/GPU information. -char_select_handle(16#0818, CSocket, GID, Version, _) -> - ?MODULE:char_select(CSocket, GID, Version); +char_select_handle(16#0818, _) -> + ?MODULE:char_select(); %% @doc Unknown command handler. Do nothing. -char_select_handle(Command, CSocket, GID, Version, _) -> - log(GID, "(char_select) dismissed packet ~4.16.0b", [Command]), - ?MODULE:char_select(CSocket, GID, Version). +char_select_handle(Command, _) -> + log("(char_select) dismissed packet ~4.16.0b", [Command]), + ?MODULE:char_select(). %% @doc Load the selected character in the start lobby and start the main game's loop. -char_select_load(CSocket, GID, Version, Number) -> - User = egs_db:users_select(GID), +char_select_load(Number) -> + User = egs_db:users_select(get(gid)), [{status, 1}, {char, Char}, {options, Options}] = data_load(User#users.folder, Number), << Name:512/bits, _/bits >> = Char, NewRow = User#users{charnumber=Number, charname=Name}, egs_db:users_insert(NewRow), - char_load(CSocket, GID, Char, Options, Number), - send_021b(CSocket, GID), - area_load(CSocket, GID, 1100000, 0, 1, 1), - ssl:setopts(CSocket, [{active, true}]), - ?MODULE:loop(CSocket, GID, Version). + char_load(Char, Options, Number), + send_021b(), + area_load(1100000, 0, 1, 1), + ssl:setopts(get(socket), [{active, true}]), + ?MODULE:loop(<< >>). %% @doc Load the given character's data. @@ -222,25 +227,25 @@ data_load(Folder, Number) -> %% @doc Load and send the character information to the client. -char_load(CSocket, GID, Char, Options, Number) -> - send_0d01(CSocket, GID, Char, Options), +char_load(Char, Options, Number) -> + send_0d01(Char, Options), % 0246 - send_0a0a(CSocket, GID), - send_1006(CSocket, GID, 5), - send_1005(CSocket, GID, Char), - send_1006(CSocket, GID, 12), + send_0a0a(), + send_1006(5), + send_1005(Char), + send_1006(12), % 0210 - send_0222(CSocket, GID), - send_1500(CSocket, GID, Char, Number), - send_1501(CSocket, GID), - send_1512(CSocket, GID), + send_0222(), + send_1500(Char, Number), + send_1501(), + send_1512(), % 0303 - send_1602(CSocket, GID). + send_1602(). %% @doc Load the given map as a mission counter. -counter_load(CSocket, GID, QuestID, ZoneID, MapID, EntryID) -> - OldUser = egs_db:users_select(GID), +counter_load(QuestID, ZoneID, MapID, EntryID) -> + OldUser = egs_db:users_select(get(gid)), User = OldUser#users{areatype=counter, questid=QuestID, zoneid=ZoneID, mapid=MapID, entryid=EntryID, savedquestid=OldUser#users.questid, savedzoneid=OldUser#users.zoneid, savedmapid=ZoneID, savedentryid=MapID}, egs_db:users_insert(User), @@ -251,26 +256,26 @@ counter_load(CSocket, GID, QuestID, ZoneID, MapID, EntryID) -> % broadcast unspawn to other people lists:foreach(fun(Other) -> Other#users.pid ! {psu_player_unspawn, User} end, egs_db:users_select_others_in_area(OldUser)), % load counter - send_0c00(CSocket, GID, 16#7fffffff), - send_020e(CSocket, QuestFile), - send_0a05(CSocket, GID), + send_0c00(16#7fffffff), + send_020e(QuestFile), + send_0a05(), % 010d - send_0200(CSocket, GID, mission), - send_020f(CSocket, ZoneFile, 0, 16#ff), - send_0205(CSocket, 0, 0, 0, 0), - send_100e(CSocket, GID, 16#7fffffff, 0, 0, AreaName, EntryID), - send_0215(CSocket, GID, 0), - send_0215(CSocket, GID, 0), - send_020c(CSocket), - send_1202(CSocket, GID), - send_1204(CSocket, GID), - send_1206(CSocket, GID), - send_1207(CSocket, GID), - send_1212(CSocket, GID), - send_0201(CSocket, GID, User, Char), - send_0a06(CSocket, GID), - send_0208(CSocket, GID), - send_0236(CSocket, GID). + send_0200(mission), + send_020f(ZoneFile, 0, 16#ff), + send_0205(0, 0, 0, 0), + send_100e(16#7fffffff, 0, 0, AreaName, EntryID), + send_0215(0), + send_0215(0), + send_020c(), + send_1202(), + send_1204(), + send_1206(), + send_1207(), + send_1212(), + send_0201(User, Char), + send_0a06(), + send_0208(), + send_0236(). %% @doc Return the current season information. @@ -314,15 +319,15 @@ area_get_season(QuestID) -> %% @doc Load the given map as a standard lobby. -area_load(CSocket, GID, QuestID, ZoneID, MapID, EntryID) -> - OldUser = egs_db:users_select(GID), +area_load(QuestID, ZoneID, MapID, EntryID) -> + OldUser = egs_db:users_select(get(gid)), [{type, AreaType}, {file, QuestFile}|StartInfo] = proplists:get_value(QuestID, ?QUESTS, [{type, undefined}, {file, undefined}]), [IsStart, InstanceID, RealZoneID, RealMapID, RealEntryID] = case AreaType of mission -> if ZoneID =:= 65535 -> [{start, [TmpZoneID, TmpMapID, TmpEntryID]}] = StartInfo, - [true, GID, TmpZoneID, TmpMapID, TmpEntryID]; - true -> [false, GID, ZoneID, MapID, EntryID] + [true, OldUser#users.gid, TmpZoneID, TmpMapID, TmpEntryID]; + true -> [false, OldUser#users.gid, ZoneID, MapID, EntryID] end; myroom -> if ZoneID =:= 0 -> @@ -340,9 +345,9 @@ area_load(CSocket, GID, QuestID, ZoneID, MapID, EntryID) -> end, User = OldUser#users{instanceid=InstanceID, areatype=AreaType, questid=QuestID, zoneid=RealZoneID, mapid=RealMapID, entryid=RealEntryID}, egs_db:users_insert(User), - area_load(CSocket, GID, AreaType, IsStart, OldUser, User, QuestFile, ZoneFile, AreaName). + area_load(AreaType, IsStart, OldUser, User, QuestFile, ZoneFile, AreaName). -area_load(CSocket, GID, AreaType, IsStart, OldUser, User, QuestFile, ZoneFile, AreaName) -> +area_load(AreaType, IsStart, OldUser, User, QuestFile, ZoneFile, AreaName) -> [{status, 1}, {char, Char}, {options, Options}] = data_load(User#users.folder, User#users.charnumber), QuestChange = if OldUser#users.questid /= User#users.questid, QuestFile /= undefined -> true; true -> false end, if ZoneFile =:= undefined -> @@ -361,157 +366,152 @@ area_load(CSocket, GID, AreaType, IsStart, OldUser, User, QuestFile, ZoneFile, A if QuestChange =:= true -> % reload the character if entering or leaving the room quest if OldUser#users.questid =:= 1120000; User#users.questid =:= 1120000 -> - char_load(CSocket, GID, Char, Options, User#users.charnumber); + char_load(Char, Options, User#users.charnumber); true -> ignore end, % load new quest - send_0c00(CSocket, GID, User#users.questid), - send_020e(CSocket, QuestFile); + send_0c00(User#users.questid), + send_020e(QuestFile); true -> ignore end, if IsStart =:= true -> - send_0215(CSocket, GID, 16#ffffffff); + send_0215(16#ffffffff); true -> ignore end, if ZoneChange =:= true -> % load new zone - send_0a05(CSocket, GID), + send_0a05(), if AreaType =:= lobby -> - send_0111(CSocket, GID); + send_0111(); true -> ignore end, % 010d - send_0200(CSocket, GID, AreaType), + send_0200(AreaType), Layout = if IsStart =:= true -> crypto:rand_uniform(0, 4); true -> 0 end, - send_020f(CSocket, ZoneFile, Layout, Season); + send_020f(ZoneFile, Layout, Season); true -> ignore end, - send_0205(CSocket, User#users.zoneid, User#users.mapid, User#users.entryid, IsSeasonal), - send_100e(CSocket, GID, User#users.questid, User#users.zoneid, User#users.mapid, AreaName, 16#ffffffff), + send_0205(User#users.zoneid, User#users.mapid, User#users.entryid, IsSeasonal), + send_100e(User#users.questid, User#users.zoneid, User#users.mapid, AreaName, 16#ffffffff), if AreaType =:= mission -> - send_0215(CSocket, GID, 0), + send_0215(0), if IsStart =:= true -> - send_0215(CSocket, GID, 0), - send_0c09(CSocket, GID); + send_0215(0), + send_0c09(); true -> ignore end; true -> - send_020c(CSocket) + send_020c() end, case AreaType of myroom -> - myroom_send_packet(CSocket, "p/packet1332.bin"), - send_1202(CSocket, GID), - send_1204(CSocket, GID), - send_1206(CSocket, GID); + myroom_send_packet("p/packet1332.bin"), + send_1202(), + send_1204(), + send_1206(); mission -> - send_1202(CSocket, GID), - send_1204(CSocket, GID), - send_1206(CSocket, GID), - send_1207(CSocket, GID); + send_1202(), + send_1204(), + send_1206(), + send_1207(); _ -> ignore end, if AreaType /= spaceport -> - send_1212(CSocket, GID); + send_1212(); true -> ignore end, if AreaType =:= myroom -> - myroom_send_packet(CSocket, "p/packet1309.bin"); + myroom_send_packet("p/packet1309.bin"); true -> ignore end, - send_0201(CSocket, GID, User, Char), + send_0201(User, Char), if ZoneChange =:= true -> - send_0a06(CSocket, GID); + send_0a06(); true -> ignore end, - send_0233(CSocket, GID, egs_db:users_select_others_in_area(User)), - send_0208(CSocket, GID), - send_0236(CSocket, GID). + send_0233(egs_db:users_select_others_in_area(User)), + send_0208(), + send_0236(). -myroom_send_packet(CSocket, Filename) -> +myroom_send_packet(Filename) -> {ok, << _:32, File/bits >>} = file:read_file(Filename), - egs_proto:packet_send(CSocket, File). - -%% @doc Alias for the game main's loop when the buffer is empty. - -loop(CSocket, GID, Version) -> - loop(CSocket, GID, Version, << >>). + send(File). %% @doc Game's main loop. -loop(CSocket, GID, Version, SoFar) -> +loop(SoFar) -> receive {psu_broadcast, Orig} -> << A:64/bits, _:32, B:96/bits, _:64, C/bits >> = Orig, - Packet = << A/binary, 16#00011300:32, B/binary, 16#00011300:32, GID:32/little-unsigned-integer, C/binary >>, - egs_proto:packet_send(CSocket, Packet), - ?MODULE:loop(CSocket, GID, Version, SoFar); + GID = get(gid), + send(<< A/binary, 16#00011300:32, B/binary, 16#00011300:32, GID:32/little-unsigned-integer, C/binary >>), + ?MODULE:loop(SoFar); {psu_chat, ChatGID, ChatName, ChatModifiers, ChatMessage} -> - send_0304(CSocket, Version, ChatGID, ChatName, ChatModifiers, ChatMessage), - ?MODULE:loop(CSocket, GID, Version, SoFar); + send_0304(ChatGID, ChatName, ChatModifiers, ChatMessage), + ?MODULE:loop(SoFar); {psu_keepalive} -> - egs_proto:send_keepalive(CSocket), - ?MODULE:loop(CSocket, GID, Version, SoFar); + egs_proto:send_keepalive(get(socket)), + ?MODULE:loop(SoFar); {psu_player_spawn, Spawn} -> - send_spawn(CSocket, GID, Spawn), - ?MODULE:loop(CSocket, GID, Version, SoFar); + send_spawn(Spawn), + ?MODULE:loop(SoFar); {psu_player_unspawn, Spawn} -> - send_0204(CSocket, GID, Spawn#users.gid, Spawn#users.lid, 5), - ?MODULE:loop(CSocket, GID, Version, SoFar); + send_0204(Spawn#users.gid, Spawn#users.lid, 5), + ?MODULE:loop(SoFar); {ssl, _, Data} -> {Packets, Rest} = egs_proto:packet_split(<< SoFar/bits, Data/bits >>), - [dispatch(CSocket, GID, Version, Orig) || Orig <- Packets], - ?MODULE:loop(CSocket, GID, Version, Rest); + [dispatch(Orig) || Orig <- Packets], + ?MODULE:loop(Rest); {ssl_closed, _} -> exit(ssl_closed); {ssl_error, _, _} -> exit(ssl_error); _ -> - ?MODULE:loop(CSocket, GID, Version, SoFar) + ?MODULE:loop(SoFar) after 1000 -> reload, - ?MODULE:loop(CSocket, GID, Version, SoFar) + ?MODULE:loop(SoFar) end. %% @doc Dispatch the command to the right handler. -dispatch(CSocket, GID, Version, Orig) -> +dispatch(Orig) -> {command, Command, Channel, Data} = egs_proto:packet_parse(Orig), case Channel of ignore -> ignore; - 1 -> broadcast(Command, GID, Orig); - _ -> handle(Command, CSocket, GID, Version, Data) + 1 -> broadcast(Command, Orig); + _ -> handle(Command, Data) end. %% @doc Position change broadcast handler. Save the position and then dispatch it. -broadcast(16#0503, GID, Orig) -> +broadcast(16#0503, Orig) -> << 100:32/little-unsigned-integer, 16#050301:24/unsigned-integer, _:360, Direction:32/bits, Coords:96/bits, _:96, QuestID:32/little-unsigned-integer, ZoneID:32/little-unsigned-integer, MapID:32/little-unsigned-integer, EntryID:32/little-unsigned-integer, _:32 >> = Orig, - User = egs_db:users_select(GID), + User = egs_db:users_select(get(gid)), NewUser = User#users{direction=Direction, coords=Coords, questid=QuestID, zoneid=ZoneID, mapid=MapID, entryid=EntryID}, egs_db:users_insert(NewUser), - broadcast(default, GID, Orig); + broadcast(default, Orig); %% @doc Stand still broadcast handler. Save the position and then dispatch it. -broadcast(16#0514, GID, Orig) -> +broadcast(16#0514, Orig) -> << _:320, _:96, Direction:32/bits, Coords:96/bits, QuestID:32/little-unsigned-integer, ZoneID:32/little-unsigned-integer, MapID:32/little-unsigned-integer, EntryID:32/little-unsigned-integer, _/bits >> = Orig, - User = egs_db:users_select(GID), + User = egs_db:users_select(get(gid)), NewUser = User#users{direction=Direction, coords=Coords, questid=QuestID, zoneid=ZoneID, mapid=MapID, entryid=EntryID}, egs_db:users_insert(NewUser), - broadcast(default, GID, Orig); + broadcast(default, Orig); %% @doc Default broadcast handler. Dispatch the command to everyone. %% We clean up the command and use the real GID and LID of the user, disregarding what was sent and possibly tampered with. %% Only a handful of commands are allowed to broadcast. An user tampering with it would get disconnected instantly. %% @todo Don't query the user data everytime! Keep an User instead of a GID probably. -broadcast(Command, GID, Orig) +broadcast(Command, Orig) when Command =:= 16#0101; Command =:= 16#0102; Command =:= 16#0104; @@ -520,6 +520,7 @@ broadcast(Command, GID, Orig) Command =:= 16#050f; Command =:= default -> << _:32, A:64/bits, _:64, B:192/bits, _:64, C/bits >> = Orig, + GID = get(gid), case egs_db:users_select(GID) of error -> ignore; @@ -532,7 +533,7 @@ broadcast(Command, GID, Orig) %% @doc Movement (non-broadcast) handler. Do nothing. -handle(16#0102, _, _, _, _) -> +handle(16#0102, _) -> ignore; %% @doc Weapon equip, unequip, item drop, and more... handler. Do what we can. @@ -543,9 +544,10 @@ handle(16#0102, _, _, _, _) -> %% @todo Apparently B is always ItemID+1. Not sure why. %% @todo Currently use a separate file for the data sent for the weapons. -handle(16#0105, CSocket, GID, _, Data) -> +handle(16#0105, Data) -> << _:32, A:32/little-unsigned-integer, ItemID:8, Action:8, _:8, B:8, C:32/little-unsigned-integer, _/bits >> = Data, - log(GID, "0105 action ~b item ~b (~b ~b ~b)", [Action, ItemID, A, B, C]), + log("0105 action ~b item ~b (~b ~b ~b)", [Action, ItemID, A, B, C]), + GID = get(gid), Category = case ItemID of % units would be 8, traps would be 12 19 -> 2; % armor @@ -576,14 +578,12 @@ handle(16#0105, CSocket, GID, _, Data) -> none -> File = << >>; _ -> {ok, File} = file:read_file(Filename) end, - Packet = << 16#01050300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, + send(<< 16#01050300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, GID:32/little-unsigned-integer, A:32/little-unsigned-integer, ItemID, Action, Category, B, C:32/little-unsigned-integer, - File/binary >>, - egs_proto:packet_send(CSocket, Packet); + File/binary >>); 2 -> % unequip item - Packet = << 16#01050300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, - 0:64, GID:32/little-unsigned-integer, A:32/little-unsigned-integer, ItemID, Action, Category, B, C:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet); + send(<< 16#01050300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, + 0:64, GID:32/little-unsigned-integer, A:32/little-unsigned-integer, ItemID, Action, Category, B, C:32/little-unsigned-integer >>); 5 -> % drop item ignore; _ -> @@ -593,76 +593,76 @@ handle(16#0105, CSocket, GID, _, Data) -> %% @doc Shop listing request. Currently return the normal item shop for everything. %% @todo Return the other shops appropriately. -handle(16#010a, CSocket, GID, _, Data) -> +handle(16#010a, Data) -> << _:32, A:32/little-unsigned-integer, B:32/little-unsigned-integer, C:32/little-unsigned-integer >> = Data, - log(GID, "shop listing request (~b, ~b, ~b)", [A, B, C]), + log("shop listing request (~b, ~b, ~b)", [A, B, C]), + GID = get(gid), {ok, File} = file:read_file("p/itemshop.bin"), - Packet = << 16#010a0300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, - GID:32/little-unsigned-integer, 0:64, GID:32/little-unsigned-integer, 0:32, File/binary >>, - egs_proto:packet_send(CSocket, Packet); + send(<< 16#010a0300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, + GID:32/little-unsigned-integer, 0:64, GID:32/little-unsigned-integer, 0:32, File/binary >>); %% @doc Character death, and more, handler. Warp to 4th floor for now. %% @todo Recover from death correctly. -handle(16#0110, CSocket, GID, _, Data) -> +handle(16#0110, Data) -> << _:32, A:32/little-unsigned-integer, B:32/little-unsigned-integer, C:32/little-unsigned-integer >> = Data, case B of 2 -> % triggered when looking at the type menu - send_0113(CSocket, GID); + send_0113(); 3 -> % type change - log(GID, "changed type to ~b", [C]); + log("changed type to ~b", [C]); 7 -> % player death - area_load(CSocket, GID, 1100000, 0, 4, 6); + area_load(1100000, 0, 4, 6); 10 -> % online status change - log(GID, "changed status to ~b", [C]); + log("changed status to ~b", [C]); _ -> - log(GID, "unknown 0110 (~b, ~b, ~b)", [A, B, C]) + log("unknown 0110 (~b, ~b, ~b)", [A, B, C]) end; %% @doc Uni cube handler. -handle(16#021d, CSocket, _, _, _) -> - send_021e(CSocket); +handle(16#021d, _) -> + send_021e(); %% @doc Uni selection handler. %% When selecting 'Your room', load a default room. %% When selecting 'Reload', reload the character in the current lobby. %% @todo There's probably an entryid given in the uni selection packet. -handle(16#021f, CSocket, GID, _, << Uni:32/little-unsigned-integer, _/bits >>) -> +handle(16#021f, << Uni:32/little-unsigned-integer, _/bits >>) -> case Uni of 0 -> % cancelled uni selection ignore; 16#ffffffff -> - log(GID, "uni selection (my room)"), - send_0230(CSocket, GID), + log("uni selection (my room)"), + send_0230(), % 0220 - area_load(CSocket, GID, 1120000, 0, 100, 0); + area_load(1120000, 0, 100, 0); _ -> - log(GID, "uni selection (reload)"), - send_0230(CSocket, GID), + log("uni selection (reload)"), + send_0230(), % 0220 % force reloading the character and data files (hack) - User = egs_db:users_select(GID), + User = egs_db:users_select(get(gid)), NewRow = User#users{questid=1120000, zoneid=undefined}, egs_db:users_insert(NewRow), - area_load(CSocket, GID, User#users.questid, User#users.zoneid, User#users.mapid, User#users.entryid) + area_load(User#users.questid, User#users.zoneid, User#users.mapid, User#users.entryid) end; %% @doc Shortcut changes handler. Do nothing. %% @todo Save it. -handle(16#0302, _, GID, _, _) -> - log(GID, "dismissed shortcut changes"); +handle(16#0302, _) -> + log("dismissed shortcut changes"); %% @doc Chat broadcast handler. Dispatch the message to everyone (for now). %% We must take extra precautions to handle different versions of the game correctly. %% Disregard the name sent by the server in later versions of the game. Use the name saved in memory instead, to prevent client-side editing. %% @todo Only broadcast to people in the same map. -handle(16#0304, _, GID, Version, Data) -> - User = egs_db:users_select(GID), - case Version of +handle(16#0304, Data) -> + User = egs_db:users_select(get(gid)), + case get(version) of 0 -> % AOTI v2.000 << _:64, Modifiers:128/bits, Message/bits >> = Data; _ -> % Above @@ -671,20 +671,20 @@ handle(16#0304, _, GID, Version, Data) -> [LogName|_] = re:split(User#users.charname, "\\0\\0", [{return, binary}]), [TmpMessage|_] = re:split(Message, "\\0\\0", [{return, binary}]), LogMessage = re:replace(TmpMessage, "\\n", " ", [global, {return, binary}]), - log(GID, "chat from ~s: ~s", [[re:replace(LogName, "\\0", "", [global, {return, binary}])], [re:replace(LogMessage, "\\0", "", [global, {return, binary}])]]), - lists:foreach(fun(X) -> X#users.pid ! {psu_chat, GID, User#users.charname, Modifiers, Message} end, egs_db:users_select_all()); + log("chat from ~s: ~s", [[re:replace(LogName, "\\0", "", [global, {return, binary}])], [re:replace(LogMessage, "\\0", "", [global, {return, binary}])]]), + lists:foreach(fun(X) -> X#users.pid ! {psu_chat, get(gid), User#users.charname, Modifiers, Message} end, egs_db:users_select_all()); %% @todo Handle this packet properly. %% @todo Spawn cleared response event shouldn't be handled following this packet but when we see the spawn actually dead HP-wise. -handle(16#0402, CSocket, GID, _, Data) -> +handle(16#0402, Data) -> << SpawnID:32/little-unsigned-integer, _:64, Type:32/little-unsigned-integer, _:64 >> = Data, case Type of 7 -> % spawn cleared @todo 1201 sent back with same values apparently, but not always if SpawnID =:= 70 -> - send_1205(CSocket, GID, 53, 0); + send_1205(53, 0); SpawnID =:= 100 -> - send_1205(CSocket, GID, 55, 0); + send_1205(55, 0); true -> ignore end; @@ -694,112 +694,112 @@ handle(16#0402, CSocket, GID, _, Data) -> %% @todo Handle this packet. -handle(16#0404, CSocket, GID, _, Data) -> +handle(16#0404, Data) -> << A:32/little-unsigned-integer, B:32/little-unsigned-integer >> = Data, - log(GID, "unknown command 0404: ~b ~b", [A, B]), - send_1205(CSocket, GID, A, B); + log("unknown command 0404: ~b ~b", [A, B]), + send_1205(A, B); %% @doc Map change handler. %% Rooms are handled differently than normal lobbies. %% @todo When changing lobby to the room, 0230 must also be sent. Same when going from room to lobby. -handle(16#0807, CSocket, GID, _, Data) -> +handle(16#0807, Data) -> << QuestID:32/little-unsigned-integer, ZoneID:16/little-unsigned-integer, MapID:16/little-unsigned-integer, EntryID:16/little-unsigned-integer, _/bits >> = Data, - log(GID, "map change (~b,~b,~b,~b)", [QuestID, ZoneID, MapID, EntryID]), - area_load(CSocket, GID, QuestID, ZoneID, MapID, EntryID); + log("map change (~b,~b,~b,~b)", [QuestID, ZoneID, MapID, EntryID]), + area_load(QuestID, ZoneID, MapID, EntryID); %% @doc Mission counter handler. -handle(16#0811, CSocket, GID, _, Data) -> +handle(16#0811, Data) -> << QuestID:32/little-unsigned-integer, ZoneID:16/little-unsigned-integer, MapID:16/little-unsigned-integer, EntryID:16/little-unsigned-integer, _/bits >> = Data, - log(GID, "mission counter (~b,~b,~b,~b)", [QuestID, ZoneID, MapID, EntryID]), - counter_load(CSocket, GID, QuestID, ZoneID, MapID, EntryID); + log("mission counter (~b,~b,~b,~b)", [QuestID, ZoneID, MapID, EntryID]), + counter_load(QuestID, ZoneID, MapID, EntryID); %% @doc Leave mission counter handler. Lobby values depend on which counter was entered. -handle(16#0812, CSocket, GID, _, _) -> - User = egs_db:users_select(GID), - area_load(CSocket, GID, User#users.savedquestid, User#users.savedzoneid, User#users.zoneid, User#users.mapid); +handle(16#0812, _) -> + User = egs_db:users_select(get(gid)), + area_load(User#users.savedquestid, User#users.savedzoneid, User#users.zoneid, User#users.mapid); %% @doc Item description request. %% @todo Send something other than just "dammy". -handle(16#0a10, CSocket, GID, _, << ItemID:32/unsigned-integer >>) -> - send_0a11(CSocket, GID, ItemID, "dammy"); +handle(16#0a10, << ItemID:32/unsigned-integer >>) -> + send_0a11(ItemID, "dammy"); %% @doc Start mission handler. %% @todo Forward the mission start to other players of the same party, whatever their location is. -handle(16#0c01, CSocket, GID, _, << QuestID:32/little-unsigned-integer >>) -> - log(GID, "start mission ~b", [QuestID]), - send_170c(CSocket, GID), - send_1020(CSocket, GID), - send_1015(CSocket, GID, QuestID), - send_0c02(CSocket, GID); +handle(16#0c01, << QuestID:32/little-unsigned-integer >>) -> + log("start mission ~b", [QuestID]), + send_170c(), + send_1020(), + send_1015(QuestID), + send_0c02(); %% @doc Counter quests files request handler? Send huge number of quest files. %% @todo Handle correctly. -handle(16#0c05, CSocket, GID, _, _) -> - User = egs_db:users_select(GID), +handle(16#0c05, _) -> + User = egs_db:users_select(get(gid)), [{quests, Filename}, {bg, _}, {options, _}] = proplists:get_value(User#users.entryid, ?COUNTERS), - send_0c06(CSocket, Filename); + send_0c06(Filename); %% @doc Lobby transport handler? Just ignore the meseta price for now and send the player where he wanna be! %% @todo Handle correctly. -handle(16#0c07, CSocket, GID, _, _) -> - send_0c08(CSocket, GID, ok); +handle(16#0c07, _) -> + send_0c08(ok); %% @doc Abort mission handler. -handle(16#0c0e, CSocket, GID, _, _) -> - send_1006(CSocket, GID, 11), - User = egs_db:users_select(GID), +handle(16#0c0e, _) -> + send_1006(11), + User = egs_db:users_select(get(gid)), if User#users.areatype =:= mission -> - area_load(CSocket, GID, User#users.savedquestid, User#users.savedzoneid, User#users.savedmapid, User#users.savedentryid); + area_load(User#users.savedquestid, User#users.savedzoneid, User#users.savedmapid, User#users.savedentryid); true -> ignore end; %% @doc Counter available mission list request handler. %% @todo Temporarily allow rare mission and LL all difficulties to all players. -handle(16#0c0f, CSocket, GID, _, _) -> - User = egs_db:users_select(GID), +handle(16#0c0f, _) -> + User = egs_db:users_select(get(gid)), [{quests, _}, {bg, _}, {options, Options}] = proplists:get_value(User#users.entryid, ?COUNTERS), - send_0c10(CSocket, GID, Options); + send_0c10(Options); %% @doc Set flag handler. Associate a new flag with the character. %% Just reply with a success value for now. %% @todo God save the flags. -handle(16#0d04, CSocket, GID, _, Data) -> +handle(16#0d04, Data) -> << Flag:128/bits, A:16/bits, _:8, B/bits >> = Data, - log(GID, "flag handler for ~s", [re:replace(Flag, "\\0+", "", [global, {return, binary}])]), - Packet = << 16#0d040300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Flag/binary, A/binary, 1, B/binary >>, - egs_proto:packet_send(CSocket, Packet); + log("flag handler for ~s", [re:replace(Flag, "\\0+", "", [global, {return, binary}])]), + GID = get(gid), + send(<< 16#0d040300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Flag/binary, A/binary, 1, B/binary >>); %% @doc Options changes handler. -handle(16#0d07, _, GID, _, << Options/bits >>) -> - log(GID, "options changes"), - User = egs_db:users_select(GID), +handle(16#0d07, << Options/bits >>) -> + log("options changes"), + User = egs_db:users_select(get(gid)), file:write_file(io_lib:format("save/~s/~b-character.options", [User#users.folder, User#users.charnumber]), Options); %% @doc Hit handler. %% @todo Finish the work on it. %% @todo First value at 2C is the number of hits. We don't need to know it though. -handle(16#0e00, CSocket, GID, _, Data) -> +handle(16#0e00, Data) -> << _:96, Hits/bits >> = Data, - handle_hits(CSocket, GID, Hits); + handle_hits(Hits); %% @doc Object event handler. %% @todo Handle all events appropriately. -handle(16#0f0a, CSocket, GID, _, Data) -> +handle(16#0f0a, Data) -> << _:96, A:32/little-unsigned-integer, _:64, B:32/little-unsigned-integer, _:272, Action:8, _/bits >> = Data, case Action of 0 -> % warp @@ -808,9 +808,9 @@ handle(16#0f0a, CSocket, GID, _, Data) -> ignore; 12 -> % key % it's more than one 0f0a event actually... @todo hack - send_1205(CSocket, GID, 215, 0), - send_1213(CSocket, GID, 8, 1), - send_1205(CSocket, GID, 202, 0); + send_1205(215, 0), + send_1213(8, 1), + send_1205(202, 0); 13 -> % button on ignore; 14 -> % button off @@ -823,136 +823,142 @@ handle(16#0f0a, CSocket, GID, _, Data) -> ignore; 24 -> % key activation (has key) % it's more than one 0f0a event actually... @todo hack - send_1205(CSocket, GID, 244, 0), - send_1205(CSocket, GID, 54, 0), - send_1213(CSocket, GID, 0, 1); + send_1205(244, 0), + send_1205(54, 0), + send_1213(0, 1); 25 -> % sit on chair - send_1211(CSocket, GID, A, B, 8, 0); + send_1211(A, B, 8, 0); 26 -> % sit out of chair - send_1211(CSocket, GID, A, B, 8, 2); + send_1211(A, B, 8, 2); %~ 30 -> % @todo (phantom ruins block 4) %~ ignore; _ -> - log(GID, "object event ~b", [Action]) + log("object event ~b", [Action]) end; %% @doc Party information recap request. %% @todo Handle when the party already exists! And stop doing it wrong. -handle(16#1705, CSocket, GID, _, _) -> - User = egs_db:users_select(GID), - send_1706(CSocket, GID, User#users.charname); +handle(16#1705, _) -> + User = egs_db:users_select(get(gid)), + send_1706(User#users.charname); %% @doc Mission selected handler. Send the currently selected mission. %% @todo Probably need to dispatch that info to other party members in the same counter. -handle(16#1707, _, _, _, _) -> +handle(16#1707, _) -> ignore; %% @doc Party settings request handler. Item distribution is random for now. %% @todo Handle correctly. -handle(16#1709, CSocket, GID, _, _) -> - send_170a(CSocket, GID); +handle(16#1709, _) -> + send_170a(); %% @doc Counter-related handler. -handle(16#170b, CSocket, GID, _, _) -> - send_170c(CSocket, GID); +handle(16#170b, _) -> + send_170c(); %% @doc Counter initialization handler? Send the code for the background image to use. %% @todo Handle correctly. -handle(16#1710, CSocket, GID, _, _) -> - User = egs_db:users_select(GID), +handle(16#1710, _) -> + User = egs_db:users_select(get(gid)), [{quests, _}, {bg, Background}, {options, _}] = proplists:get_value(User#users.entryid, ?COUNTERS), - send_1711(CSocket, GID, Background); + send_1711(Background); %% @doc Dialog request handler. Do what we can. %% @todo Handle correctly. -handle(16#1a01, CSocket, GID, _, Data) -> +handle(16#1a01, Data) -> << _:32, A:8, B:8, _:16, C:8, _/bits >> = Data, case [A, B, C] of [ 0, 0, 2] -> - log(GID, "lumilass (and more?)"), - send_1a03(CSocket, GID); + log("lumilass (and more?)"), + send_1a03(); [ 0, 0, 3] -> - log(GID, "pp cube"), - send_1a04(CSocket, GID); + log("pp cube"), + send_1a04(); [ 0, 0, 9] -> - log(GID, "types menu"), - send_1a07(CSocket, GID); + log("types menu"), + send_1a07(); [80, 0, _] -> - log(GID, "npc dialog choice"), - send_1a02(CSocket, GID, 0, 17, 17, 3, 9); + log("npc dialog choice"), + send_1a02(0, 17, 17, 3, 9); [90, 0, _] -> % All the replies from here are consistent but their effect is unknown. - log(GID, "1a01 unknown (~b ~b ~b)", [A, B, C]), - send_1a02(CSocket, GID, 0, 5, 1, 4, 5); + log("1a01 unknown (~b ~b ~b)", [A, B, C]), + send_1a02(0, 5, 1, 4, 5); [91, 0, _] -> - log(GID, "1a01 unknown (~b ~b ~b)", [A, B, C]), - send_1a02(CSocket, GID, 0, 5, 5, 4, 7); + log("1a01 unknown (~b ~b ~b)", [A, B, C]), + send_1a02(0, 5, 5, 4, 7); [92, 0, _] -> - log(GID, "1a01 unknown (~b ~b ~b)", [A, B, C]), - send_1a02(CSocket, GID, 0, 5, 0, 4, 0); + log("1a01 unknown (~b ~b ~b)", [A, B, C]), + send_1a02(0, 5, 0, 4, 0); [93, 0, _] -> - log(GID, "1a01 unknown (~b ~b ~b)", [A, B, C]), - send_1a02(CSocket, GID, 0, 5, 18, 4, 0); + log("1a01 unknown (~b ~b ~b)", [A, B, C]), + send_1a02(0, 5, 18, 4, 0); [ _, 2, _] -> - log(GID, "1a01 unknown (~b ~b ~b)", [A, B, C]), - send_1a02(CSocket, GID, 0, 0, 1, 0, 0); + log("1a01 unknown (~b ~b ~b)", [A, B, C]), + send_1a02(0, 0, 1, 0, 0); _ -> - log(GID, "1a01 unknown (~b ~b ~b) - do nothing", [A, B, C]) + log("1a01 unknown (~b ~b ~b) - do nothing", [A, B, C]) end; %% @doc Unknown command handler. Do nothing. -handle(Command, _, GID, _, _) -> - log(GID, "dismissed packet ~4.16.0b", [Command]). +handle(Command, _) -> + log("dismissed packet ~4.16.0b", [Command]). %% @doc Handle all hits received. %% @todo Finish the work on it. -%~ log_hits(GID, Data) -> +%~ log_hits(Data) -> %~ << A:32/unsigned-integer, B:32/unsigned-integer, C:32/unsigned-integer, D:32/unsigned-integer, %~ E:32/unsigned-integer, F:32/unsigned-integer, G:32/unsigned-integer, H:32/unsigned-integer, %~ I:32/unsigned-integer, J:32/unsigned-integer, K:32/unsigned-integer, L:32/unsigned-integer, %~ M:32/unsigned-integer, N:32/unsigned-integer, O:32/unsigned-integer, P:32/unsigned-integer, %~ Q:32/unsigned-integer, R:32/unsigned-integer, S:32/unsigned-integer, T:32/unsigned-integer, _/bits >> = Data, - %~ log(GID, "hit!~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b", [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T]). + %~ log("hit!~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b~n ~8.16.0b ~8.16.0b ~8.16.0b ~8.16.0b", [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T]). -handle_hits(_, _, << >>) -> +handle_hits(<< >>) -> ok; -handle_hits(CSocket, GID, Data) -> +handle_hits(Data) -> %~ log_hits(GID, Data), << A:224/bits, B:128/bits, _:288/bits, Rest/bits >> = Data, + GID = get(gid), PlayerHP = 4401, TargetHP = 0, Damage = 58008, - Packet = << 16#0e070300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, + send(<< 16#0e070300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 1:32/little-unsigned-integer, 16#01050000:32, Damage:32/little-unsigned-integer, A/binary, 0:64, PlayerHP:32/little-unsigned-integer, 0:32, 16#01000200:32, - 0:32, TargetHP:32, 0:32, B/binary, 16#04320000:32, 16#80000000:32, 16#26030000:32, 16#89068d00:32, 16#0c1c0105:32 >>, - egs_proto:packet_send(CSocket, Packet), - handle_hits(CSocket, GID, Rest). + 0:32, TargetHP:32, 0:32, B/binary, 16#04320000:32, 16#80000000:32, 16#26030000:32, 16#89068d00:32, 16#0c1c0105:32 >>), + handle_hits(Rest). + +%% @doc Send the given packet to the client. +%% @todo Consolidate the receive and send functions better. + +send(Packet) -> + egs_proto:packet_send(get(socket), Packet). %% @todo Possibly related to 010d. Just send seemingly safe values. -send_0111(CSocket, GID) -> - Packet = << 16#01110300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, - GID:32/little-unsigned-integer, 0:32, 6:32/little-unsigned-integer, 0:32 >>, - egs_proto:packet_send(CSocket, Packet). +send_0111() -> + GID = get(gid), + send(<< 16#01110300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, + GID:32/little-unsigned-integer, 0:32, 6:32/little-unsigned-integer, 0:32 >>). %% @todo Types capability list. -send_0113(CSocket, GID) -> +send_0113() -> {ok, File} = file:read_file("p/typesinfo.bin"), - Packet = << 16#01130300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, GID:32/little-unsigned-integer, File/binary >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#01130300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, GID:32/little-unsigned-integer, File/binary >>). %% @doc Send the zone initialization notification. -send_0200(CSocket, GID, ZoneType) -> +send_0200(ZoneType) -> case ZoneType of mission -> Var = << 16#06000500:32, 16#01000000:32, 0:64, 16#00040000:32, 16#00010000:32, 16#00140000:32 >>; @@ -961,123 +967,118 @@ send_0200(CSocket, GID, ZoneType) -> _ -> Var = << 16#00040000:32, 0:160, 16#00140000:32 >> end, - Packet = << 16#02000300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, 16#01000000:32, - 16#ffffffff:32, Var/binary, 16#ffffffff:32, 16#ffffffff:32 >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#02000300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, 16#01000000:32, + 16#ffffffff:32, Var/binary, 16#ffffffff:32, 16#ffffffff:32 >>). %% @todo Figure out what the other things are. -send_0201(CSocket, GID, User, Char) -> +send_0201(User, Char) -> #users{gid=CharGID, lid=CharLID, questid=QuestID, zoneid=ZoneID, mapid=MapID, entryid=EntryID} = User, {ok, File} = file:read_file("p/packet0201.bin"), << _:96, A:32/bits, _:96, B:32/bits, _:256, D:32/bits, _:2656, After/bits >> = File, - Packet = << 16#02010300:32, 0:32, A/binary, CharGID:32/little-unsigned-integer, 0:64, B/binary, GID:32/little-unsigned-integer, + GID = get(gid), + send(<< 16#02010300:32, 0:32, A/binary, CharGID:32/little-unsigned-integer, 0:64, B/binary, GID:32/little-unsigned-integer, 0:64, CharLID:32/little-unsigned-integer, CharGID:32/little-unsigned-integer, 0:96, D/binary, QuestID:32/little-unsigned-integer, ZoneID:32/little-unsigned-integer, MapID:32/little-unsigned-integer, EntryID:32/little-unsigned-integer, 0:192, QuestID:32/little-unsigned-integer, - ZoneID:32/little-unsigned-integer, MapID:32/little-unsigned-integer, EntryID:32/little-unsigned-integer, Char/binary, After/binary >>, - egs_proto:packet_send(CSocket, Packet). + ZoneID:32/little-unsigned-integer, MapID:32/little-unsigned-integer, EntryID:32/little-unsigned-integer, Char/binary, After/binary >>). %% @doc Hello packet, always sent on client connection. -send_0202(CSocket) -> - egs_proto:packet_send(CSocket, << 16#02020300:32, 0:352 >>). +send_0202() -> + send(<< 16#02020300:32, 0:352 >>). %% @todo Not sure. Used for unspawning, and more. -send_0204(CSocket, GID, PlayerGID, PlayerLID, Action) -> - Packet = << 16#02040300:32, 0:32, 16#00001200:32, PlayerGID:32/little-unsigned-integer, 0:64, +send_0204(PlayerGID, PlayerLID, Action) -> + GID = get(gid), + send(<< 16#02040300:32, 0:32, 16#00001200:32, PlayerGID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, PlayerGID:32/little-unsigned-integer, - PlayerLID:32/little-unsigned-integer, Action:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). + PlayerLID:32/little-unsigned-integer, Action:32/little-unsigned-integer >>). %% @doc Send the map ID to be loaded by the client. %% @todo Last two values are unknown. -send_0205(CSocket, MapType, MapNumber, MapEntry, IsSeasonal) -> - Packet = << 16#02050300:32, 0:288, 16#ffffffff:32, MapType:32/little-unsigned-integer, - MapNumber:32/little-unsigned-integer, MapEntry:32/little-unsigned-integer, 0:56, IsSeasonal >>, - egs_proto:packet_send(CSocket, Packet). +send_0205(MapType, MapNumber, MapEntry, IsSeasonal) -> + send(<< 16#02050300:32, 0:288, 16#ffffffff:32, MapType:32/little-unsigned-integer, + MapNumber:32/little-unsigned-integer, MapEntry:32/little-unsigned-integer, 0:56, IsSeasonal >>). %% @doc Indicate to the client that loading should finish. %% @todo Last value seems to be 2 most of the time. Never 0 though. Apparently counters have it at 4. -send_0208(CSocket, GID) -> - Packet = << 16#02080300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 2:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). +send_0208() -> + GID = get(gid), + send(<< 16#02080300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 2:32/little-unsigned-integer >>). %% @todo No idea what this one does. For unknown reasons it uses channel 2. -send_020c(CSocket) -> - Packet = << 16#020c020c:32, 16#fffff20c:32, 0:256 >>, - egs_proto:packet_send(CSocket, Packet). +send_020c() -> + send(<< 16#020c020c:32, 16#fffff20c:32, 0:256 >>). %% @doc Send the quest file to be loaded. %% @todo Probably should try sending the checksum like value (right before the file) and see if it magically fixes anything. -send_020e(CSocket, Filename) -> +send_020e(Filename) -> {ok, File} = file:read_file(Filename), Size = byte_size(File), - Packet = << 16#020e0300:32, 0:288, Size:32/little-unsigned-integer, 0:32, File/binary, 0:32 >>, - egs_proto:packet_send(CSocket, Packet). + send(<< 16#020e0300:32, 0:288, Size:32/little-unsigned-integer, 0:32, File/binary, 0:32 >>). %% @doc Send the zone file to be loaded. -send_020f(CSocket, Filename, Layout, Season) -> +send_020f(Filename, Layout, Season) -> {ok, File} = file:read_file(Filename), Size = byte_size(File), - Packet = << 16#020f0300:32, 0:288, Layout, Season, 0:16, Size:32/little-unsigned-integer, File/binary >>, - egs_proto:packet_send(CSocket, Packet). + send(<< 16#020f0300:32, 0:288, Layout, Season, 0:16, Size:32/little-unsigned-integer, File/binary >>). %% @todo No idea what this do. Nor why it's sent twice when loading a counter. -send_0215(CSocket, GID, N) -> - Packet = << 16#02150300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, N:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). +send_0215(N) -> + GID = get(gid), + send(<< 16#02150300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, N:32/little-unsigned-integer >>). %% @todo End of character loading. Just send it. -send_021b(CSocket, GID) -> - Packet = << 16#021b0300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>, - egs_proto:packet_send(CSocket, Packet). +send_021b() -> + GID = get(gid), + send(<< 16#021b0300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>). %% @doc Send the list of available universes. -send_021e(CSocket) -> +send_021e() -> {ok, << File:1184/bits, _/bits >>} = file:read_file("p/unicube.bin"), [StrCount] = io_lib:format("~b", [egs_db:users_count()]), UCS2Count = << << X:8, 0:8 >> || X <- StrCount >>, PaddingSize = (12 - byte_size(UCS2Count)) * 8, - Packet = << 16#021e0300:32, 0:288, File/binary, UCS2Count/binary, 0:PaddingSize >>, - egs_proto:packet_send(CSocket, Packet). + send(<< 16#021e0300:32, 0:288, File/binary, UCS2Count/binary, 0:PaddingSize >>). %% @doc Send the current universe name and number. %% @todo Currently only have universe number 2, named EGS Test. -send_0222(CSocket, GID) -> +send_0222() -> UCS2Name = << << X:8, 0:8 >> || X <- "EGS Test" >>, - Packet = << 16#02220300:32, 0:32, 16#00001200:32, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, - 2:32/little-unsigned-integer, 0:32, UCS2Name/binary, 0:16 >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#02220300:32, 0:32, 16#00001200:32, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, + 2:32/little-unsigned-integer, 0:32, UCS2Name/binary, 0:16 >>). %% @todo Not sure. Sent when going to or from room. -send_0230(CSocket, GID) -> - Packet = << 16#02300300:32, 0:32, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>, - egs_proto:packet_send(CSocket, Packet). +send_0230() -> + GID = get(gid), + send(<< 16#02300300:32, 0:32, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>). %% @todo Figure out what the other things are. -send_0233(CSocket, GID, Users) -> +send_0233(Users) -> NbUsers = length(Users), case NbUsers of 0 -> ignore; _ -> + GID = get(gid), Header = << 16#02330300:32, 0:32, 16#00001200:32, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, NbUsers:32/little-unsigned-integer >>, Contents = build_0233_contents(Users), - Packet = << Header/binary, Contents/binary >>, - egs_proto:packet_send(CSocket, Packet) + send(<< Header/binary, Contents/binary >>) end. build_0233_contents([]) -> @@ -1104,150 +1105,149 @@ build_0233_contents(Users) -> %% @doc Center the camera on the player, if possible. %% @todo Probably. -send_0236(CSocket, GID) -> - Packet = << 16#02360300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>, - egs_proto:packet_send(CSocket, Packet). +send_0236() -> + GID = get(gid), + send(<< 16#02360300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>). -%% @doc Send a chat command. AOTI v2.000 version of the command. +%% @doc Send a chat command. Handled differently at v2.0000 and all versions starting somewhere above that. -send_0304(CSocket, 0, FromGID, _, Modifiers, Message) -> - Packet = << 16#03040300:32/unsigned-integer, 0:288, 16#00001200:32, FromGID:32/little-unsigned-integer, Modifiers:128/bits, Message/bits >>, - egs_proto:packet_send(CSocket, Packet); - -%% @doc Send a chat command. AOTI since an unknown version of the game. - -send_0304(CSocket, _, FromGID, FromName, Modifiers, Message) -> - Packet = << 16#03040300:32, 0:288, 16#00001200:32, FromGID:32/little-unsigned-integer, Modifiers:128/bits, FromName:512/bits, Message/bits >>, - egs_proto:packet_send(CSocket, Packet). +send_0304(FromGID, FromName, Modifiers, Message) -> + case get(version) of + 0 -> send(<< 16#03040300:32/unsigned-integer, 0:288, 16#00001200:32, FromGID:32/little-unsigned-integer, Modifiers:128/bits, Message/bits >>); + _ -> send(<< 16#03040300:32, 0:288, 16#00001200:32, FromGID:32/little-unsigned-integer, Modifiers:128/bits, FromName:512/bits, Message/bits >>) + end. %% @todo Inventory related. No idea what it does. -send_0a05(CSocket, GID) -> - Packet = << 16#0a050300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>, - egs_proto:packet_send(CSocket, Packet). +send_0a05() -> + GID = get(gid), + send(<< 16#0a050300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>). %% @todo Inventory related. Figure out everything in this packet and handle it correctly. %% @todo It sends 60 values so it's probably some kind of options for all 60 items in the inventory? -send_0a06(CSocket, GID) -> +send_0a06() -> {ok, << _:32, A:96/bits, _:32, B:96/bits, _:32, C:1440/bits, _:32, D/bits >>} = file:read_file("p/packet0a06.bin"), - egs_proto:packet_send(CSocket, << A/binary, GID:32/little-unsigned-integer, B/binary, GID:32/little-unsigned-integer, C/binary, GID:32/little-unsigned-integer, D/binary >>). + GID = get(gid), + send(<< A/binary, GID:32/little-unsigned-integer, B/binary, GID:32/little-unsigned-integer, C/binary, GID:32/little-unsigned-integer, D/binary >>). %% @todo Inventory. Figure out everything in this packet and handle it correctly. -send_0a0a(CSocket, GID) -> +send_0a0a() -> {ok, << _:32, A:224/bits, _:32, B/bits >>} = file:read_file("p/packet0a0a.bin"), - egs_proto:packet_send(CSocket, << A/binary, GID:32/little-unsigned-integer, B/binary >>). + GID = get(gid), + send(<< A/binary, GID:32/little-unsigned-integer, B/binary >>). %% @doc Item description. -send_0a11(CSocket, GID, ItemID, ItemDesc) -> +send_0a11(ItemID, ItemDesc) -> Size = 1 + length(ItemDesc), UCS2Desc = << << X:8, 0:8 >> || X <- ItemDesc >>, - Packet = << 16#0a110300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, - ItemID:32/unsigned-integer, Size:32/little-unsigned-integer, UCS2Desc/binary, 0:16 >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#0a110300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, + ItemID:32/unsigned-integer, Size:32/little-unsigned-integer, UCS2Desc/binary, 0:16 >>). %% @doc Init quest. -send_0c00(CSocket, GID, QuestID) -> - Packet = << 16#0c000300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, QuestID:32/little-unsigned-integer, +send_0c00(QuestID) -> + GID = get(gid), + send(<< 16#0c000300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, QuestID:32/little-unsigned-integer, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, - 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32 >>, - egs_proto:packet_send(CSocket, Packet). + 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32 >>). %% @todo Figure out last 4 bytes! -send_0c02(CSocket, GID) -> - Packet = << 16#0c020300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96 >>, - egs_proto:packet_send(CSocket, Packet). +send_0c02() -> + GID = get(gid), + send(<< 16#0c020300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96 >>). %% @doc Send the huge pack of quest files available in the counter. -send_0c06(CSocket, Filename) -> +send_0c06(Filename) -> {ok, << File/bits >>} = file:read_file(Filename), - Packet = << 16#0c060300:32, 0:288, 1:32/little-unsigned-integer, File/binary >>, - egs_proto:packet_send(CSocket, Packet). + send(<< 16#0c060300:32, 0:288, 1:32/little-unsigned-integer, File/binary >>). %% @doc Reply whether the player is allowed to use the transport option. %% Use 'ok' for allowing it, and 'error' otherwise. -send_0c08(CSocket, GID, Response) -> +send_0c08(Response) -> Value = if Response =:= ok -> 0; true -> 1 end, - Packet = << 16#0c080300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Value:32 >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#0c080300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Value:32 >>). %% @doc Send the trial start notification. -send_0c09(CSocket, GID) -> - Packet = << 16#0c090300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:128 >>, - egs_proto:packet_send(CSocket, Packet). +send_0c09() -> + GID = get(gid), + send(<< 16#0c090300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:128 >>). %% @doc Send the counter's mission options (0 = invisible, 2 = disabled, 3 = available). -send_0c10(CSocket, GID, Options) -> - Packet = << 16#0c100300:32, 0:32, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, - 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Options/binary >>, - egs_proto:packet_send(CSocket, Packet). +send_0c10(Options) -> + GID = get(gid), + send(<< 16#0c100300:32, 0:32, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, + 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Options/binary >>). %% @doc Send the data for the selected character. %% @todo The large chunk of 0s can have some values set... but what are they used for? %% @todo The values after the Char variable are the flags. Probably use bits to define what flag is and isn't set. Handle correctly. -send_0d01(CSocket, GID, Char, Options) -> - Packet = << 16#0d010300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Char/binary, +send_0d01(Char, Options) -> + GID = get(gid), + send(<< 16#0d010300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Char/binary, 16#ffbbef1c:32, 16#f8ff0700:32, 16#fc810916:32, 16#7802134c:32, 16#b0c0040f:32, 16#7cf0e583:32, 16#b7bce0c6:32, 16#7ff8f963:32, 16#3fd7ffff:32, 16#fff7ffff:32, 16#f3ff63e0:32, 16#1fe00000:32, - 0:7744, Options/binary >>, - egs_proto:packet_send(CSocket, Packet). + 0:7744, Options/binary >>). %% @doc Send the character list for selection. -send_0d03(CSocket, GID, Data0, Data1, Data2, Data3) -> +send_0d03(Data0, Data1, Data2, Data3) -> [{status, Status0}, {char, Char0}|_] = Data0, [{status, Status1}, {char, Char1}|_] = Data1, [{status, Status2}, {char, Char2}|_] = Data2, [{status, Status3}, {char, Char3}|_] = Data3, - Packet = << 16#0d030300:32/unsigned-integer, 0:32, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:104, + GID = get(gid), + send(<< 16#0d030300:32/unsigned-integer, 0:32, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:104, Status0:8/unsigned-integer, 0:48, Char0/binary, 0:520, Status1:8/unsigned-integer, 0:48, Char1/binary, 0:520, Status2:8/unsigned-integer, 0:48, Char2/binary, 0:520, - Status3:8/unsigned-integer, 0:48, Char3/binary, 0:512 >>, - egs_proto:packet_send(CSocket, Packet). + Status3:8/unsigned-integer, 0:48, Char3/binary, 0:512 >>). %% @doc Send the character flags list. This is the whole list of available values, not the character's. %% Sent without fragmentation on official for unknown reasons. Do the same here. -send_0d05(CSocket, GID) -> +send_0d05() -> {ok, Flags} = file:read_file("p/flags.bin"), + GID = get(gid), Packet = << 16#0d050300:32, 0:32, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Flags/binary >>, Size = 4 + byte_size(Packet), - ssl:send(CSocket, << Size:32/little-unsigned-integer, Packet/binary >>). + ssl:send(get(socket), << Size:32/little-unsigned-integer, Packet/binary >>). %% @todo Figure out what the packet is. -send_1005(CSocket, GID, Char) -> +send_1005(Char) -> {ok, File} = file:read_file("p/packet1005.bin"), << _:352, Before:160/bits, _:608, After/bits >> = File, << Name:512/bits, _/bits >> = Char, - Packet = << 16#10050300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Before/binary, GID:32/little-unsigned-integer, 0:64, Name/binary, After/binary >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#10050300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Before/binary, GID:32/little-unsigned-integer, 0:64, Name/binary, After/binary >>). %% @doc Party-related command probably controlling the party state. %% Value 11 aborts the mission. %% @todo Figure out what the packet is. -send_1006(CSocket, GID, N) -> - Packet = << 16#10060300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, N:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). +send_1006(N) -> + GID = get(gid), + send(<< 16#10060300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, N:32/little-unsigned-integer >>). %% @doc Send the player's current location. -send_100e(CSocket, GID, QuestID, ZoneID, MapID, Location, CounterID) -> +send_100e(QuestID, ZoneID, MapID, Location, CounterID) -> UCS2Location = << << X:8, 0:8 >> || X <- Location >>, + GID = get(gid), Packet = << 16#100e0300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 1:32/little-unsigned-integer, MapID:16/little-unsigned-integer, ZoneID:16/little-unsigned-integer, QuestID:32/little-unsigned-integer, UCS2Location/binary >>, @@ -1258,176 +1258,176 @@ send_100e(CSocket, GID, QuestID, ZoneID, MapID, Location, CounterID) -> _ -> Footer = << CounterID:32/little-unsigned-integer, 1:32/little-unsigned-integer >> end, - egs_proto:packet_send(CSocket, << Packet/binary, 0:PaddingSize, Footer/binary >>). + send(<< Packet/binary, 0:PaddingSize, Footer/binary >>). %% @doc Send the mission's quest file when starting a new mission. %% @todo Handle correctly. 0:32 is actually a missing value. Value before that is unknown too. -send_1015(CSocket, GID, QuestID) -> +send_1015(QuestID) -> [{type, _}, {file, QuestFile}|_] = proplists:get_value(QuestID, ?QUESTS), {ok, File} = file:read_file(QuestFile), Size = byte_size(File), - Packet = << 16#10150300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, - QuestID:32/little-unsigned-integer, 16#01010000:32, 0:32, Size:32/little-unsigned-integer, File/binary >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#10150300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, + QuestID:32/little-unsigned-integer, 16#01010000:32, 0:32, Size:32/little-unsigned-integer, File/binary >>). %% @todo Totally unknown. -send_1020(CSocket, GID) -> - Packet = << 16#10200300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>, - egs_proto:packet_send(CSocket, Packet). +send_1020() -> + GID = get(gid), + send(<< 16#10200300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64 >>). %% @todo Figure out what this packet does. Sane values for counter and missions for now. -send_1202(CSocket, GID) -> - Packet = << 16#12020300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, 16#10000000:32, 0:64, 16#14000000:32, 0:32 >>, - egs_proto:packet_send(CSocket, Packet). +send_1202() -> + GID = get(gid), + send(<< 16#12020300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, 16#10000000:32, 0:64, 16#14000000:32, 0:32 >>). %% @todo Figure out what this packet does. Seems it's the same values all the time. -send_1204(CSocket, GID) -> - Packet = << 16#12040300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, 16#20000000:32, 0:256 >>, - egs_proto:packet_send(CSocket, Packet). +send_1204() -> + GID = get(gid), + send(<< 16#12040300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, 16#20000000:32, 0:256 >>). %% @doc Object events response? %% @todo Figure things out. -send_1205(CSocket, GID, A, B) -> - Packet = << 16#12050300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, A:32/little-unsigned-integer, B:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). +send_1205(A, B) -> + GID = get(gid), + send(<< 16#12050300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, A:32/little-unsigned-integer, B:32/little-unsigned-integer >>). %% @todo Figure out what this packet does. Sane values for counter and missions for now. -send_1206(CSocket, GID) -> - Packet = << 16#12060300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, 16#80020000:32, 0:5120 >>, - egs_proto:packet_send(CSocket, Packet). +send_1206() -> + GID = get(gid), + send(<< 16#12060300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, 16#80020000:32, 0:5120 >>). %% @todo Figure out what this packet does. Sane values for counter and missions for now. -send_1207(CSocket, GID) -> +send_1207() -> + GID = get(gid), Chunk = << 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 0:224, 16#0000ffff:32, 16#ff000000:32, 16#64000a00:32 >>, - Packet = << 16#12070300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, - Chunk/binary, Chunk/binary, Chunk/binary, Chunk/binary, Chunk/binary, Chunk/binary >>, - egs_proto:packet_send(CSocket, Packet). + send(<< 16#12070300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, + Chunk/binary, Chunk/binary, Chunk/binary, Chunk/binary, Chunk/binary, Chunk/binary >>). %% @todo Object interaction? Figure out. C probably the interaction type. -send_1211(CSocket, GID, A, B, C, D) -> - Packet = << 16#12110300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, A:32/little-unsigned-integer, B:32/little-unsigned-integer, C:32/little-unsigned-integer, D:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). +send_1211(A, B, C, D) -> + GID = get(gid), + send(<< 16#12110300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, A:32/little-unsigned-integer, B:32/little-unsigned-integer, C:32/little-unsigned-integer, D:32/little-unsigned-integer >>). %% @doc Make the client load the quest previously sent. -send_1212(CSocket, GID) -> - Packet = << 16#12120300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:19264 >>, - egs_proto:packet_send(CSocket, Packet). +send_1212() -> + GID = get(gid), + send(<< 16#12120300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:19264 >>). %% @todo Not sure. Related to keys. -send_1213(CSocket, GID, A, B) -> - Packet = << 16#12120300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, A:32/little-unsigned-integer, B:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). +send_1213(A, B) -> + GID = get(gid), + send(<< 16#12120300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, A:32/little-unsigned-integer, B:32/little-unsigned-integer >>). %% @doc Send the player's partner card. -send_1500(CSocket, GID, Char, Number) -> +send_1500(Char, Number) -> << CharInfo:576/bits, _/bits >> = Char, - Packet = << 16#15000300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, CharInfo/binary, 0:3072, 16#010401:24, Number:8, 0:64 >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#15000300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, CharInfo/binary, 0:3072, 16#010401:24, Number:8, 0:64 >>). %% @todo Send an empty partner card list. -send_1501(CSocket, GID) -> - Packet = << 16#15010300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96 >>, - egs_proto:packet_send(CSocket, Packet). +send_1501() -> + GID = get(gid), + send(<< 16#15010300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96 >>). %% @todo Send an empty blacklist. -send_1512(CSocket, GID) -> - Packet = << 16#15120300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:46144 >>, - egs_proto:packet_send(CSocket, Packet). +send_1512() -> + GID = get(gid), + send(<< 16#15120300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:46144 >>). %% @doc Send the player's NPC and PM information. -send_1602(CSocket, GID) -> +send_1602() -> {ok, File} = file:read_file("p/npc.bin"), - Packet = << 16#16020300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, File/binary >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#16020300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, File/binary >>). %% @doc Party information. %% @todo Handle existing parties. -send_1706(CSocket, GID, CharName) -> - Packet = << 16#17060300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, +send_1706(CharName) -> + GID = get(gid), + send(<< 16#17060300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#00000300:32, 16#d5c0faff:32, 0:64, CharName/binary, 16#78000000:32, 16#01010000:32, - 0:1536, 16#0100c800:32, 16#0601010a:32, 16#ffffffff:32, 0:32 >>, - egs_proto:packet_send(CSocket, Packet). + 0:1536, 16#0100c800:32, 16#0601010a:32, 16#ffffffff:32, 0:32 >>). %% @doc Party settings. Item distribution is random for now. %% @todo Handle correctly. -send_170a(CSocket, GID) -> - Packet = << 16#170a0300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#01010c08:32 >>, - egs_proto:packet_send(CSocket, Packet). +send_170a() -> + GID = get(gid), + send(<< 16#170a0300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#01010c08:32 >>). %% @todo Find what the heck this packet is. -send_170c(CSocket, GID) -> +send_170c() -> {ok, File} = file:read_file("p/packet170c.bin"), - Packet = << 16#170c0300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, File/binary >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#170c0300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, File/binary >>). %% @doc Send the background to use for the counter. %% @todo Background has more info past the first byte. -send_1711(CSocket, GID, Background) -> - Packet = << 16#17110300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Background:32/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). +send_1711(Background) -> + GID = get(gid), + send(<< 16#17110300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, Background:32/little-unsigned-integer >>). %% @doc Unknown dialog-related handler. %% @todo Everything! -send_1a02(CSocket, GID, A, B, C, D, E) -> - Packet = << 16#1a020300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, A:32/little-unsigned-integer, - B:16/little-unsigned-integer, C:16/little-unsigned-integer, D:16/little-unsigned-integer, E:16/little-unsigned-integer >>, - egs_proto:packet_send(CSocket, Packet). +send_1a02(A, B, C, D, E) -> + GID = get(gid), + send(<< 16#1a020300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, A:32/little-unsigned-integer, + B:16/little-unsigned-integer, C:16/little-unsigned-integer, D:16/little-unsigned-integer, E:16/little-unsigned-integer >>). %% @doc Lumilass handler. Possibly more. %% @todo Figure out how Lumilass work exactly. The 4 bytes before the file may vary. -send_1a03(CSocket, GID) -> +send_1a03() -> {ok, File} = file:read_file("p/lumilassA.bin"), - Packet = << 16#1a030300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, File/binary >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#1a030300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, File/binary >>). %% @doc PP cube handler. %% @todo The 4 bytes before the file may vary. Everything past that is the same. Figure things out. -send_1a04(CSocket, GID) -> +send_1a04() -> {ok, File} = file:read_file("p/ppcube.bin"), - Packet = << 16#1a040300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, File/binary >>, - egs_proto:packet_send(CSocket, Packet). + GID = get(gid), + send(<< 16#1a040300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:96, File/binary >>). %% @doc Types menu handler. %% @todo Handle correctly. -send_1a07(CSocket, GID) -> - Packet = << 16#1a070300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#085b5d0a:32, 16#3a200000:32, 0:32, - 16#01010101:32, 16#01010101:32, 16#01010101:32, 16#01010101:32 >>, - egs_proto:packet_send(CSocket, Packet). +send_1a07() -> + GID = get(gid), + send(<< 16#1a070300:32, 0:160, 16#00011300:32, GID:32/little-unsigned-integer, 0:64, 16#085b5d0a:32, 16#3a200000:32, 0:32, + 16#01010101:32, 16#01010101:32, 16#01010101:32, 16#01010101:32 >>). %% @todo Figure out what the other things are and do it right. %% @todo Temporarily send 233 until the correct process is figured out. %% Should be something along the lines of 203 201 204. -send_spawn(CSocket, GID, _) -> - send_0233(CSocket, GID, egs_db:users_select_others_in_area(egs_db:users_select(GID))). +send_spawn(_) -> + send_0233(egs_db:users_select_others_in_area(egs_db:users_select(get(gid)))). %% @doc Log message to the console. -log(GID, Message) -> - io:format("game (~.10b): ~s~n", [GID, Message]). +log(Message) -> + io:format("game (~p): ~s~n", [get(gid), Message]). -log(GID, Message, Format) -> - RealMessage = io_lib:format(Message, Format), - log(GID, RealMessage). +log(Message, Format) -> + FormattedMessage = io_lib:format(Message, Format), + log(FormattedMessage).