hytale 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00d6560e486235a55ab2450d656b61421b6fddb8b9b40c3c3226a1df754f8724
4
- data.tar.gz: 81194f4a57ffb54903a48f2d6361e101ab35049245cd654e7631e81f30949187
3
+ metadata.gz: c1ecc8d6da6ef59f252740739b05fad04f49e0a6cd628c94a085a6dbd43cb918
4
+ data.tar.gz: 804efc4f07dc64ac5a68ba5d28043c1ac0094f6c42ba6cf1734c7f1c985b4380
5
5
  SHA512:
6
- metadata.gz: 80355bb885697efd829c1807ba7ae3d91436fb654ee1a40f0af1a4d3de0a5f6794ffa0801e3b06f5f832b8b01b7d27cccc25c0d8b96882fee57a32eb283696af
7
- data.tar.gz: d219d3d0363f5e4fd79d1affb96e272c53a5e3565d0ede2a9a2837e269aa449441324dbd55b44c9f6dd07c1bf2930ca415baffe29e1926b2ba8a3590f22ca9ef
6
+ metadata.gz: a1be72b9c7373e5fa9b682758b5b756384d25350df8b14fc5bdb555a09f9577f93ecd50b297b56c436e94dee76872c2d6972316d6b202f4b9ada06b335980aec
7
+ data.tar.gz: e73dc31ff553991792fafbc611d58c037770af922366075e27a1982294eb90618c58fb89cd38d552bfbcc394084f3a24f0eb0f163bf4f73e826a2f4604c8647d
data/README.md CHANGED
@@ -363,6 +363,57 @@ item.durability_percent # => 14.9
363
363
  item.damaged? # => true
364
364
  ```
365
365
 
366
+ **Respawn points:**
367
+
368
+ ```ruby
369
+ player.respawn_points.each do |point|
370
+ puts "#{point.name} at #{point.position}"
371
+ end
372
+ # => Kweebec village at (-2150.5, 119.05, -403.1)
373
+ # => Bed at (-795.1, 121.05, 29.47)
374
+ ```
375
+
376
+ **Death positions:**
377
+
378
+ ```ruby
379
+ player.death_positions.each do |death|
380
+ puts "Died on day #{death.day} at #{death.position}"
381
+ end
382
+ # => Died on day 68 at (-677.67, 27.99, -153.48)
383
+ ```
384
+
385
+ **Discovered instances (dungeons, locations):**
386
+
387
+ ```ruby
388
+ player.discovered_instances
389
+ # => ["4781d0dd-5370-4962-a1fc-521ec7ff3e23", ...]
390
+ ```
391
+
392
+ **Player state:**
393
+
394
+ ```ruby
395
+ player.flying? # => false
396
+ player.first_spawn? # => false
397
+ player.head_rotation # => Rotation object (separate from body)
398
+ player.current_world # => "default"
399
+ ```
400
+
401
+ **Saved hotbars:**
402
+
403
+ ```ruby
404
+ player.saved_hotbars # => [ItemStorage, ...]
405
+ player.current_hotbar_index # => 0
406
+ ```
407
+
408
+ **Progress tracking:**
409
+
410
+ ```ruby
411
+ player.known_recipes # => []
412
+ player.unique_item_usages # => ["Upgrade_Backpack_1"]
413
+ player.active_objectives # => []
414
+ player.reputation_data # => {}
415
+ ```
416
+
366
417
  ### Zones and Regions
367
418
 
368
419
  Hytale organizes the world into zones (biomes) and regions (areas within zones):
@@ -880,6 +931,55 @@ process.pid # => 12345
880
931
  | `player_skins` | List all cached PlayerSkin objects |
881
932
  | `player_skin(uuid)` | Find PlayerSkin by UUID |
882
933
 
934
+ ### Hytale::Client::Player
935
+
936
+ | Method | Description |
937
+ |--------|-------------|
938
+ | `name` | Player display name |
939
+ | `uuid` | Player UUID |
940
+ | `position` | Current Position object |
941
+ | `rotation` | Current body Rotation object |
942
+ | `head_rotation` | Current head Rotation object |
943
+ | `velocity` | Current Vector3 velocity |
944
+ | `stats` | EntityStats object (health, stamina, etc.) |
945
+ | `inventory` | Inventory object |
946
+ | `game_mode` | Current game mode ("Adventure", "Creative", etc.) |
947
+ | `current_world` | Current world name |
948
+ | `discovered_zones` | Array of Zone::Region objects |
949
+ | `discovered_instances` | Array of discovered dungeon/location UUIDs |
950
+ | `respawn_points` | Array of RespawnPoint objects |
951
+ | `death_positions` | Array of DeathPosition objects |
952
+ | `memories` | Array of PlayerMemory objects |
953
+ | `known_recipes` | Array of learned recipe IDs |
954
+ | `unique_item_usages` | Array of used item IDs (upgrades, etc.) |
955
+ | `active_objectives` | Array of active quest UUIDs |
956
+ | `reputation_data` | Hash of faction reputations |
957
+ | `saved_hotbars` | Array of saved ItemStorage hotbars |
958
+ | `current_hotbar_index` | Currently selected hotbar slot |
959
+ | `flying?` | Is player currently flying |
960
+ | `first_spawn?` | Has player spawned before |
961
+ | `skin` | PlayerSkin object |
962
+ | `avatar_preview_path` | Path to cached avatar image |
963
+
964
+ ### Hytale::Client::Player::RespawnPoint
965
+
966
+ | Method | Description |
967
+ |--------|-------------|
968
+ | `name` | Respawn point name (e.g., "Ria's bed") |
969
+ | `position` | Exact respawn Position |
970
+ | `block_position` | Block coordinates Position |
971
+ | `x`, `y`, `z` | Shortcut position accessors |
972
+
973
+ ### Hytale::Client::Player::DeathPosition
974
+
975
+ | Method | Description |
976
+ |--------|-------------|
977
+ | `marker_id` | Death marker UUID |
978
+ | `day` | Game day of death |
979
+ | `position` | Death Position object |
980
+ | `rotation` | Death Rotation object |
981
+ | `x`, `y`, `z` | Shortcut position accessors |
982
+
883
983
  ### Hytale::Client::Zone
884
984
 
885
985
  | Method | Description |
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hytale
4
+ module Client
5
+ class Player
6
+ class DeathPosition
7
+ attr_reader :data
8
+
9
+ def initialize(data)
10
+ @data = data
11
+ end
12
+
13
+ def marker_id
14
+ data["MarkerId"]
15
+ end
16
+
17
+ def day
18
+ data["Day"]
19
+ end
20
+
21
+ def position
22
+ transform = data["Transform"] || {}
23
+
24
+ Position.new(transform["X"], transform["Y"], transform["Z"])
25
+ end
26
+
27
+ def rotation
28
+ transform = data["Transform"] || {}
29
+
30
+ Rotation.new(transform["Pitch"], transform["Yaw"], transform["Roll"])
31
+ end
32
+
33
+ def x = position.x
34
+ def y = position.y
35
+ def z = position.z
36
+
37
+ def to_s
38
+ "Death on day #{day} at #{position}"
39
+ end
40
+
41
+ def inspect
42
+ "#<DeathPosition day=#{day} position=#{position}>"
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hytale
4
+ module Client
5
+ class Player
6
+ class RespawnPoint
7
+ attr_reader :data
8
+
9
+ def initialize(data)
10
+ @data = data
11
+ end
12
+
13
+ def name
14
+ data["Name"]
15
+ end
16
+
17
+ def position
18
+ pos = data["RespawnPosition"] || {}
19
+
20
+ Position.new(pos["X"], pos["Y"], pos["Z"])
21
+ end
22
+
23
+ def block_position
24
+ pos = data["BlockPosition"] || {}
25
+
26
+ Position.new(pos["X"], pos["Y"], pos["Z"])
27
+ end
28
+
29
+ def x = position.x
30
+ def y = position.y
31
+ def z = position.z
32
+
33
+ def to_s
34
+ "#{name} at #{position}"
35
+ end
36
+
37
+ def inspect
38
+ "#<RespawnPoint name=#{name.inspect} position=#{position}>"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -22,12 +22,14 @@ module Hytale
22
22
  def position
23
23
  transform = components["Transform"] || {}
24
24
  pos = transform["Position"] || {}
25
+
25
26
  Position.new(pos["X"], pos["Y"], pos["Z"])
26
27
  end
27
28
 
28
29
  def rotation
29
30
  transform = components["Transform"] || {}
30
31
  rot = transform["Rotation"] || {}
32
+
31
33
  Rotation.new(rot["Pitch"], rot["Yaw"], rot["Roll"])
32
34
  end
33
35
 
@@ -62,8 +64,22 @@ module Hytale
62
64
  end
63
65
  end
64
66
 
67
+ def discovered_instances
68
+ @discovered_instances ||= (player_data.dig("PlayerData", "DiscoveredInstances") || []).map do |instance|
69
+ decode_binary_uuid(instance)
70
+ end.compact
71
+ end
72
+
65
73
  def respawn_points
66
- player_data.dig("PlayerData", "PerWorldData", "default", "RespawnPoints") || []
74
+ @respawn_points ||= (player_data.dig("PlayerData", "PerWorldData", "default", "RespawnPoints") || []).map do |point|
75
+ RespawnPoint.new(point)
76
+ end
77
+ end
78
+
79
+ def death_positions
80
+ @death_positions ||= (player_data.dig("PlayerData", "PerWorldData", "default", "DeathPositions") || []).map do |pos|
81
+ DeathPosition.new(pos)
82
+ end
67
83
  end
68
84
 
69
85
  def memories
@@ -72,6 +88,48 @@ module Hytale
72
88
  end
73
89
  end
74
90
 
91
+ def known_recipes
92
+ player_data.dig("PlayerData", "KnownRecipes") || []
93
+ end
94
+
95
+ def unique_item_usages
96
+ components.dig("UniqueItemUsages", "UniqueItemUsed") || []
97
+ end
98
+
99
+ def head_rotation
100
+ rot = components.dig("HeadRotation", "Rotation") || {}
101
+
102
+ Rotation.new(rot["Pitch"], rot["Yaw"], rot["Roll"])
103
+ end
104
+
105
+ def flying?
106
+ player_data.dig("PlayerData", "PerWorldData", "default", "LastMovementStates", "Flying") || false
107
+ end
108
+
109
+ def first_spawn?
110
+ player_data.dig("PlayerData", "PerWorldData", "default", "FirstSpawn") || false
111
+ end
112
+
113
+ def active_objectives
114
+ @active_objectives ||= (player_data.dig("PlayerData", "ActiveObjectiveUUIDs") || []).map do |obj|
115
+ decode_binary_uuid(obj)
116
+ end.compact
117
+ end
118
+
119
+ def reputation_data
120
+ player_data.dig("PlayerData", "ReputationData") || {}
121
+ end
122
+
123
+ def saved_hotbars
124
+ @saved_hotbars ||= (player_data.dig("HotbarManager", "SavedHotbars") || []).compact.map do |hotbar|
125
+ ItemStorage.new(hotbar)
126
+ end
127
+ end
128
+
129
+ def current_hotbar_index
130
+ player_data.dig("HotbarManager", "CurrentHotbar")
131
+ end
132
+
75
133
  def skin
76
134
  @skin ||= PlayerSkin.find(uuid)
77
135
  end
@@ -96,6 +154,18 @@ module Hytale
96
154
  raise ParseError, "Failed to parse player data: #{e.message}"
97
155
  end
98
156
  end
157
+
158
+ private
159
+
160
+ def decode_binary_uuid(data)
161
+ return nil unless data.is_a?(Hash) && data["$binary"]
162
+
163
+ bytes = Base64.decode64(data["$binary"])
164
+ return nil unless bytes.length == 16
165
+
166
+ hex = bytes.unpack1("H*")
167
+ "#{hex[0, 8]}-#{hex[8, 4]}-#{hex[12, 4]}-#{hex[16, 4]}-#{hex[20, 12]}"
168
+ end
99
169
  end
100
170
  end
101
171
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hytale
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/hytale.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "base64"
3
4
  require "json"
4
5
  require "time"
5
6
  require "zeitwerk"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hytale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Roth
@@ -9,6 +9,20 @@ bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.3'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.3'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: chunky_png
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -98,12 +112,14 @@ files:
98
112
  - lib/hytale/client/npc_memory.rb
99
113
  - lib/hytale/client/permissions.rb
100
114
  - lib/hytale/client/player.rb
115
+ - lib/hytale/client/player/death_position.rb
101
116
  - lib/hytale/client/player/entity_stats.rb
102
117
  - lib/hytale/client/player/inventory.rb
103
118
  - lib/hytale/client/player/item.rb
104
119
  - lib/hytale/client/player/item_storage.rb
105
120
  - lib/hytale/client/player/player_memory.rb
106
121
  - lib/hytale/client/player/position.rb
122
+ - lib/hytale/client/player/respawn_point.rb
107
123
  - lib/hytale/client/player/rotation.rb
108
124
  - lib/hytale/client/player/vector3.rb
109
125
  - lib/hytale/client/player_skin.rb
@@ -152,5 +168,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
168
  requirements: []
153
169
  rubygems_version: 4.0.3
154
170
  specification_version: 4
155
- summary: Ruby bindings for reading Hytale game data
171
+ summary: Ruby gem for reading Hytale game data
156
172
  test_files: []