Guest User

Untitled

a guest
Nov 15th, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.71 KB | None | 0 0
  1. defmodule MHolder do
  2.  
  3. defmacro packet {name, fields_defs} do
  4. fields_dec = Enum.map fields_defs, fn({:{}, _, [:case, var_name, val_map]}) ->
  5. var = Macro.var(var_name, __MODULE__)
  6. new_var = Macro.var(String.to_atom("#{var_name}_decoded"), __MODULE__)
  7. rest = Macro.var(:rest, __MODULE__)
  8.  
  9. cases = Enum.map val_map, fn({val, struct_name})->
  10. val = if val == :_ do {:_, [], __MODULE__} else val end
  11. quote do unquote(val) -> decode(unquote(struct_name), unquote(rest)) end
  12. end
  13.  
  14. quote do
  15. {:ok, unquote(new_var), unquote(rest)} = case unquote(var) do
  16. unquote(Enum.concat(cases))
  17. end
  18. end
  19.  
  20. ({type, name}) ->
  21. var = Macro.var(name, __MODULE__)
  22. rest = Macro.var(:rest, __MODULE__)
  23.  
  24. cond do
  25. type in [:sbyte, :byte, :int, :sint, :long, :sfloat, :float, :sshort, :short] -> #simple types
  26. dec_name = String.to_atom("decode_#{type}")
  27. quote do
  28. {:ok, unquote(var), unquote(rest)} = unquote(dec_name)(unquote(rest))
  29. end
  30.  
  31. true -> #custom types
  32. quote do
  33. {:ok, unquote(var), unquote(rest)} = decode(unquote(type), unquote(rest))
  34. end
  35. end
  36. end
  37.  
  38. IO.puts "building results"
  39. results = Enum.map fields_defs, fn({:{}, _, [:case, var_name, val_map]}) ->
  40. new_var_name = String.to_atom("#{var_name}_decoded")
  41. new_var = Macro.var(new_var_name, __MODULE__)
  42. {new_var_name, new_var}
  43. ({_, name}) ->
  44. var = Macro.var(name, __MODULE__)
  45. {name, var}
  46. end
  47. composed_result = {:%{}, [], results}
  48.  
  49. # fields_enc = Enum.map fields_defs, fn({type, name}) ->
  50. # var = Macro.var(name, __MODULE__)
  51. # rest = Macro.var(:rest, __MODULE__)
  52. # data = Macro.var(:data, __MODULE__)
  53. # cond do
  54. # type in [:sbyte, :byte, :int, :sint, :long, :sfloat, :float, :sshort, :short] -> #simple types
  55. # enc_name = String.to_atom("encode_#{type}")
  56. # quote do
  57. # unquote(rest) = unquote(rest) <> unquote(enc_name)(unquote(data).unquote(var))
  58. # end
  59. # true ->
  60. # quote do
  61. # nil
  62. # end
  63. # end
  64. # end
  65.  
  66. quote do
  67. def decode(unquote(name), rest) do
  68. unquote_splicing(fields_dec)
  69. {:ok, unquote(composed_result), rest}
  70. end
  71.  
  72. # def encode(unquote(name), data) do
  73. # rest = ""
  74. # unquote_splicing(fields_enc)
  75. # rest
  76. # end
  77. end
  78.  
  79. end
  80. end
  81.  
  82. defmodule K do
  83. require MHolder
  84.  
  85. packets =
  86. [
  87. {:ks_request_version,
  88. [
  89. {:int, :unk_int1},
  90. {:int, :client_seq},
  91. {:int, :server_seq},
  92. {:int, :crypter},
  93. {:byte, :unk_byte1}
  94. ]
  95. }
  96. ]
  97.  
  98. MHolder.packet {:ks_request_version,
  99. [
  100. {:int, :unk_int1},
  101. {:int, :client_seq},
  102. {:int, :server_seq},
  103. {:int, :crypter},
  104. {:byte, :unk_byte1},
  105. {:case, :unk_byte1,
  106. [
  107. {1, :struct1},
  108. {:_, :struct2}
  109. ]
  110. }
  111. ]
  112. }
  113. MHolder.packet {:struct1, [{:byte, :field0}]}
  114. MHolder.packet {:struct2, [{:byte, :field0}]}
  115.  
  116.  
  117. def decode_byte(<<b::8, rest::binary>>) do
  118. {:ok, b, rest}
  119. end
  120.  
  121. def decode_int(<<b::32-little, rest::binary>>) do
  122. {:ok, b, rest}
  123. end
  124. def decode(x,y) do
  125. IO.inspect {:unknown_decode,x,y}
  126. :error
  127. end
  128. def encode_byte(val) do
  129. <<val::8>>
  130. end
  131.  
  132. def encode_int(val) do
  133. <<val::32-little>>
  134. end
  135. end
  136.  
  137. {:ok, s, rest} = K.decode(:ks_request_version, "somethingebcdfgh"<> <<9>><>"jklaaaaaaaaaaaaaaa")
  138. K.encode :ks_request_version, s
Add Comment
Please, Sign In to add comment