darcsden :: alex -> aliter -> patch

a reverse-engineered Ragnarok Online server written in Erlang

patch

changes

  • src/char/char_srv.erl :: line 132

    handle_cast({save_char, C}, Sessions) ->
        log:debug("Saving character.",
                  [{character, C}]),
    
        {atomic, ok} = mnesia:transaction(fun() -> mnesia:write(C) end),
    
        {noreply, Sessions};
    
  • src/char/packets/char_packets_24.erl :: line 62

        [<<16#6d>>,
    
        [<<16#6d:16/little>>,
    
  • src/char/packets/char_packets_24.erl :: line 103

           140:16/little, % TODO (Walk speed)
    
           300:16/little, % TODO (Walk speed)
    
  • src/login/login_packets.erl :: line 11

        Version = case PacketVer of
                      20090901 ->
                          24;
                      _ ->
                          PacketVer
                  end,
    
    
  • src/login/login_packets.erl :: line 19

         PacketVer,
    
         Version,
    
  • src/zone/packets/zone_packets_24.erl :: line 71

    pack(16#86, {ActorID, {{FromX, FromY}, {ToX, ToY}}, Tick}) ->
    
    pack(16#86, {ActorID, {FromX, FromY}, {ToX, ToY}, Tick}) ->
    
  • src/zone/packets/zone_packets_24.erl :: line 76

    pack(16#87, {ActorID, {{FromX, FromY}, {ToX, ToY}}, Tick}) ->
    
    pack(16#87, {{FromX, FromY}, {ToX, ToY}, Tick}) ->
    
  • src/zone/packets/zone_packets_24.erl :: line 78

          ActorID:32/little,
          (encode_move(FromX, FromY, ToX, ToY)):6/little-binary-unit:8,
          Tick:32/little>>;
    
          Tick:32/little,
          (encode_move(FromX, FromY, ToX, ToY)):6/little-binary-unit:8>>;
    
  • src/zone/packets/zone_packets_24.erl :: line 111

    pack(16#195, {Name, Party, Guild, Position}) ->
        [<<16#195:16/little>>,
    
    pack(16#195, {AccountID, Name, Party, Guild, Position}) ->
        [<<16#195:16/little,
           AccountID:32/little>>,
    
  • src/zone/packets/zone_packets_24.erl :: line 134

    pack(16#1d7, Character) ->
        <<16#1d7:16/little,
          (Character#char.account_id):32/little,
          2:8, % TODO: ?
          (Character#char.view_weapon):16/little,
          (Character#char.view_shield):16/little>>;
    pack(16#22b, {A, C}) ->
        Gender = if
                     A#account.gender == 0 ->
                         1;
                     true ->
                         0
                 end,
    
        <<16#22b:16/little,
          (A#account.id):32/little,
          300:16/little, % TODO: Walk speed
          0:16/little, % TODO: Effect 1
          0:16/little, % TODO: Effect 2
          0:16/little, % TODO: Effect 3
          0:16, % Nothing
          (C#char.job):16/little,
          (C#char.hair_style):16/little,
          (C#char.view_weapon):16/little,
          (C#char.view_shield):16/little,
          (C#char.view_head_bottom):16/little,
          (C#char.view_head_top):16/little,
          (C#char.view_head_middle):16/little,
          (C#char.hair_colour):16/little,
          (C#char.clothes_colour):16/little,
          0:16/little, % TODO: Head direction (test this)
          (C#char.guild_id):32/little,
          (C#char.guild_id):16/little, % Guild emblem ID
          (C#char.manner):16/little, % Manners
          0:16/little, % Effect
          0:16, % Nothing,
          (C#char.karma):8, % Karma
          Gender:8, % Gender
          (encode_position(C#char.x, C#char.y, 0)):3/binary-unit:8,
          5:8,
          5:8,
          (C#char.base_level):16/little>>;
    pack(16#22c, {A, C, Tick}) ->
        Gender = if
                     A#account.gender == 0 ->
                         1;
                     true ->
                         0
                 end,
    
        <<16#22c:16/little,
          0:8, % Nothing
          (A#account.id):32/little,
          300:16/little, % TODO: Walk speed
          0:16/little, % TODO: Effect 1
          0:16/little, % TODO: Effect 2
          0:16/little, % TODO: Effect 3
          0:16, % Nothing
          (C#char.job):16/little,
          (C#char.hair_style):16/little,
          (C#char.view_weapon):16/little,
          (C#char.view_shield):16/little,
          (C#char.view_head_bottom):16/little,
          Tick:32/little,
          (C#char.view_head_top):16/little,
          (C#char.view_head_middle):16/little,
          (C#char.hair_colour):16/little,
          (C#char.clothes_colour):16/little,
          0:16/little, % TODO: Head direction (test this)
          (C#char.guild_id):32/little,
          (C#char.guild_id):16/little, % Guild emblem ID
          (C#char.manner):16/little, % Manners
          0:16/little, % Effect
          0:16, % Nothing,
          (C#char.karma):8, % Karma
          Gender:8, % Gender
          (encode_position(C#char.x, C#char.y, 0)):3/binary-unit:8,
          5:8,
          5:8,
          0:8/unit:3, % Nothing
          (C#char.base_level):16/little>>;
    
  • src/zone/packets/zone_packets_24.erl :: line 225

        X = (XNum bsl 2) bor ((YNum band 16#C0) bsr 6),
        Y = ((YNum band 16#3F) bsl 4) bor ((DNum band 16#F0) bsr 4),
    
        X = (XNum bsl 2) bor ((YNum band 16#c0) bsr 6),
        Y = ((YNum band 16#3F) bsl 4) bor ((DNum band 16#f0) bsr 4),
    
  • src/zone/packets/zone_packets_24.erl :: line 231

        A = (X bsr 2) band 16#FF,
        B = ((X bsl 6) bor ((Y bsr 4) band 16#3f)) band 16#FF,
        C = ((Y bsl 4) bor (D band 16#0f)) band 16#FF,
    
        A = (X bsr 2) band 16#ff,
        B = ((X bsl 6) bor ((Y bsr 4) band 16#3f)) band 16#ff,
        C = ((Y bsl 4) bor (D band 16#0f)) band 16#ff,
    
  • src/zone/packets/zone_packets_24.erl :: line 237

        A = (X bsr 2) band 16#FF,
        B = ((X bsl 6) bor ((X bsr 4) band 16#3f)) band 16#ff,
    
        A = (X bsr 2) band 16#ff,
        B = ((X bsl 6) bor ((Y bsr 4) band 16#3f)) band 16#ff,
    
  • src/zone/zone_fsm.erl :: line 71

                       {ok, FSM} = gen_server:call(State#zone_state.map_server,
                                                   {get_player, ActorID}),
    
                       {ActorID, FSM} = gen_server:call(State#zone_state.map_server,
                                                        {get_player, ActorID}),
    
  • src/zone/zone_fsm.erl :: line 81

    valid(map_loaded, State) ->
    
    valid(map_loaded, State = #zone_state{map_server = MapServer,
                                          account = A,
                                          char = C}) ->
        gen_server:cast(MapServer,
                        {send_to_other_players,
                         C#char.id,
                         16#1d7,
                         C}),
    
        gen_server:cast(MapServer,
                        {send_to_players_in_sight,
                         {C#char.x, C#char.y},
                         16#195,
                         {A#account.id, C#char.name, "Party Name", "Guild Name", "Tester"}}), % TODO
    
        gen_server:cast(MapServer,
                        {send_to_other_players,
                         C#char.id,
                         16#22b,
                         {A, C}}),
    
        gen_server:cast(MapServer,
                        {show_actors,
                         self()}),
    
    
  • src/zone/zone_fsm.erl :: line 162

    valid({walk, {ToX, ToY, ToD}}, State = #zone_state{tcp = TCP,
                                                 map_server = MapServer,
                                                 account = #account{id = AccountID},
                                                 char = #char{id = CharacterID,
                                                              x = X,
                                                              y = Y}}) ->
        log:debug("Received walk request.",
                  [{coords, {ToX, ToY, ToD}}]),
    
        gen_server:cast(MapServer,
                        {send_to_other_players_in_sight,
                         {X, Y},
                         CharacterID,
                         16#86,
                         {AccountID, {X, Y}, {ToX, ToY}, zone_master:tick()}}),
    
        TCP ! {16#87, {{X, Y}, {ToX, ToY}, zone_master:tick()}},
    
        {next_state, valid, State#zone_state{char = (State#zone_state.char)#char{x = ToX, y = ToY}}};
    
  • src/zone/zone_fsm.erl :: line 189

                                         char = #char{x = X, y = Y}}) ->
    
                                         char = #char{id = CharacterID,
                                                      x = X,
                                                      y = Y}}) ->
    
  • src/zone/zone_fsm.erl :: line 197

                         CharacterID,
    
  • src/zone/zone_fsm.erl :: line 224

        {next_state, StateName, StateData};
    handle_event({show_to, FSM}, StateName, StateData = #zone_state{account = A,
                                                                    char = C}) ->
        gen_fsm:send_all_state_event(FSM,
                                     {send_packet,
                                      16#1d7,
                                      C}),
    
        gen_fsm:send_all_state_event(FSM,
                                     {send_packet,
                                      16#195,
                                      {A#account.id, C#char.name, "Other Party Name", "Other Guild Name", "Other Tester"}}), % TODO
    
        gen_fsm:send_all_state_event(FSM,
                                     {send_packet,
                                      16#22c,
                                      {A, C, zone_master:tick()}}),
    
    
  • src/zone/zone_fsm.erl :: line 261

    terminate(_Reason, _StateName, #zone_state{account = #account{id = AccountID}}) ->
    
    terminate(_Reason, _StateName, #zone_state{account = #account{id = AccountID},
                                               char = Character}) ->
    
  • src/zone/zone_fsm.erl :: line 266

        {char, CharNode} = config:get_env(zone, server.char),
    
        gen_server_tcp:cast({server, CharNode},
                            {save_char, Character}),
    
    
  • src/zone/zone_map.erl :: line 95

    handle_cast({show_actors, Self}, State) ->
        lists:foreach(fun({_ID, FSM}) ->
                          if
                              FSM == Self ->
                                  log:error("Skipping self.");
                              true ->
                                  gen_fsm:send_all_state_event(FSM,
                                                               {show_to,
                                                                Self})
                          end
                      end,
                      State#map_state.players),
    
        {noreply, State};