aromancer 0.0.6 → 0.0.8

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: e0cceb1c6a55e9d5753254eb63ee964d5607a6d1cf2726bb84cce84992cdc5c8
4
- data.tar.gz: 8c9b7c1dc2d9d5366f1aa32aa0b40c60d77f31a8779f3a818da897f1e20fc73e
3
+ metadata.gz: da80d9c4f943470ac226c37651e21eaa5ee12128beb9c00264b43ace9845c61c
4
+ data.tar.gz: c55101847c0d3e6c14d7c821dc9fdf31d4e114d614d97957b7162ab995d5a02e
5
5
  SHA512:
6
- metadata.gz: 8d003f5fe55523266a5c68e7960e3e55eeaf8e2b687c5cd4d2bbeb1ea33e78d85d2c878e2309a5154c51eb84d053a1e593ddd9d7a92d9db5c031b223ef735257
7
- data.tar.gz: de814ec7a6c83262ff9d6b9b699bfb01943080ffe01a0436d570fc14a49991baea16138b9ba4741e7f654769cc2fe3a1efd2c8c71b13f11c84e0b74a1661919d
6
+ metadata.gz: 706112cc7fbf39edadef53eb6ac54a73c4e43d17f0f3b288cb9c795ba937bc38ec8427bb74ddcfbd8c84411483c520a8d9ac9b576f4371c1f0c656c2e36adb69
7
+ data.tar.gz: 91aa390ba4cf322eef5e616053cce00ebaba35ef0b9d13e051f2ba71a08bdf7c7ba5a9669d0279f88e7a67ed619a2cddba2b36f5eddc52854f691f2b74458fbc
data/.DS_Store ADDED
Binary file
data/CODE_OF_CONDUCT.md CHANGED
@@ -7,4 +7,4 @@
7
7
  * When interpreting the words and actions of others, participants should always assume good intentions.
8
8
  * Behaviour which can be reasonably considered harassment will not be tolerated.
9
9
 
10
- If you have any concerns about behaviour within this project, please contact us at ["i2097i@hotmail.com"](mailto:"i2097i@hotmail.com").
10
+ If you have any concerns about behavior within this project, please contact us at ["i2097i@hotmail.com"](mailto:"i2097i@hotmail.com").
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 i2097i
3
+ Copyright (c) 2026 Scot Reichman
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1 +1,27 @@
1
- ## aromancer gem
1
+ # [aromancer](https://rubygems.org/gems/aromancer)
2
+ ## word
3
+ ### sentence
4
+ #### scroll
5
+ #### chapter
6
+ ##### dictionary
7
+ ##### story
8
+ ###### legend
9
+ ###### [aromancer_serve](https://github.com/arowmancy/aromancer_serve)
10
+
11
+ `tl;dr`
12
+
13
+ ```bash
14
+ gem install aromancer && aromancer serve
15
+ ```
16
+ > then, from different terminal run
17
+ ```bash
18
+ aromancer
19
+ ```
20
+ #### `in-game`
21
+ > go to `configure` and verify settings
22
+
23
+ [rubygems](https://rubygems.org/gems/aromancer)
24
+ [license](http://opensource.org/licenses/MIT)
25
+ [issues](https://github.com/i2097i/aromancer/issues)
26
+
27
+ #### aromancer by scot reichman is copyright (2026)
data/aromancer.gemspec CHANGED
@@ -13,7 +13,7 @@
13
13
  require_relative "lib/aromancer/version"
14
14
 
15
15
  Gem::Specification.new do |spec|
16
- spec.name = "aromancer"
16
+ spec.name = Aromancer.to_s.downcase
17
17
  spec.version = Aromancer::VERSION
18
18
  spec.authors = ["i2097i"]
19
19
  spec.email = ["i2097i@hotmail.com"]
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.license = "MIT"
25
25
  spec.files = `git ls-files`.split("\n").reject{|p| p.match?(/^(spec|.release|.*.gem$)/)}
26
26
  spec.bindir = "bin"
27
- spec.executables = ["aromancer"]
27
+ spec.executables = [Aromancer.to_s.downcase]
28
28
  spec.require_paths = ["lib", "db"]
29
29
  spec.required_ruby_version = ">= 4.0.7"
30
30
 
data/bin/aromancer CHANGED
@@ -12,4 +12,8 @@
12
12
 
13
13
  require :aromancer.to_s
14
14
 
15
- Aromancer::Cli.run
15
+ if ARGV[0] == :serve.to_s
16
+ Aromancer::Serve.run
17
+ else
18
+ Aromancer::Cli.run
19
+ end
@@ -0,0 +1 @@
1
+ 2183e762fd2705e60f043abdb5db94f220945cad83e3dc6813bb0c03f5bd000cd3cf3b4628a470335b075ef8a6180644d9d6e18695f17bc202fe9d8cb3126068
@@ -0,0 +1 @@
1
+ ea42cb760ae909d4de2b750f3ca7f125d58b9e9147886927e8f5b7dd81a80913152d6052c1c517a99a0733e7d3b15de86d3083d1f82d5341e4c8f1e3364222a2
data/lib/aromancer/api.rb CHANGED
@@ -13,35 +13,23 @@
13
13
  module Aromancer
14
14
  class Api
15
15
 
16
- DATE_FORMAT = "%A %d %b %Y %I:%M:%S %p"
17
-
18
16
  def self.storage_headers(result)
19
17
  result.kind_of?(Aromancer::Server::InternalError) ? nil : result.headers
20
18
  end
21
19
 
22
20
  def self.register_error(response)
23
- Aromancer::Storage.set_last_error({
21
+ le = {
24
22
  status: response.status,
25
23
  headers: storage_headers(response),
26
- body: response.body.to_s[0..444]
27
- })
28
-
29
- signed_out = false
30
- signed_out = response.status == 401
31
- # error_body = nil
32
- # begin
33
- # error_body = JSON.parse(response.body)
34
- # rescue StandardError => e
35
- # end
36
-
37
- # signed_out = signed_out &&
38
- # !error_body.nil? &&
39
- # error_body.keys.include?(:error_message.to_s) &&
40
- # error_body["error_message"] == "not signed in"
41
-
42
- if signed_out
43
- Aromancer::Storage.instance.clear_cache!
44
- Aromancer::Storage.set_signed_out_flag(signed_out)
24
+ body: response.body.to_s
25
+ }
26
+ Aromancer::Storage.set_last_error(le)
27
+
28
+ if response.status == 401
29
+ Aromancer::Storage.set_signed_out_flag(true)
30
+ player = Aromancer::Storage.get_player
31
+ player["api_key"] = nil
32
+ Aromancer::Storage.set_player(player)
45
33
  end
46
34
  end
47
35
 
@@ -94,17 +82,9 @@ module Aromancer
94
82
 
95
83
  def self.sign_out
96
84
  result = Aromancer::Server.sign_out
97
- # clear storage
98
- Aromancer::Storage.instance.clear_cache!
99
- Aromancer::Storage.set_signed_out_flag(true)
100
85
  Aromancer::Storage.set_player(nil)
101
- Aromancer::Storage.set_legends(nil)
102
- Aromancer::Storage.set_arena(nil)
103
- Aromancer::Storage.set_stream(nil)
104
- Aromancer::Storage.set_last_error(nil)
105
-
106
86
  Aromancer::Websocket.instance.disconnect
107
-
87
+ Aromancer::Storage.recreate!
108
88
  register_error(result) if result.status != 200
109
89
  end
110
90
 
@@ -139,7 +119,18 @@ module Aromancer
139
119
  end
140
120
 
141
121
  def self.set_active_legend_id(active_legend_id)
122
+
123
+ previous_arena = Aromancer::Storage.get_arena
142
124
  Aromancer::Storage.set_arena(nil)
125
+
126
+ # update local storage first
127
+ player = Aromancer::Storage.get_player
128
+ unless player.nil?
129
+ previous_active_legend_id = player["active_legend_id"]
130
+ player["active_legend_id"] = active_legend_id
131
+ Aromancer::Storage.set_player(player)
132
+ end
133
+ Aromancer::Storage.instance.clear_cache!
143
134
  result = Aromancer::Server.update_player({player: {
144
135
  active_legend_id: active_legend_id,
145
136
  status: active_legend_id.nil? ? :lobby : :playing
@@ -149,6 +140,14 @@ module Aromancer
149
140
  response = JSON.parse(result.body)
150
141
  Aromancer::Storage.set_player(response)
151
142
  else
143
+ # revert local storage
144
+ player = Aromancer::Storage.get_player
145
+ unless player.nil?
146
+ player["active_legend_id"] = previous_active_legend_id
147
+ Aromancer::Storage.set_player(player)
148
+ end
149
+ Aromancer::Storage.set_arena(previous_arena)
150
+
152
151
  register_error(result)
153
152
  end
154
153
  end
@@ -164,8 +163,8 @@ module Aromancer
164
163
  end
165
164
  end
166
165
 
167
- def self.load_stream
168
- result = Aromancer::Server.get_stream
166
+ def self.load_stream(count = nil)
167
+ result = Aromancer::Server.get_stream(count)
169
168
 
170
169
  if result.status == 200
171
170
  response = JSON.parse(result.body)
@@ -186,24 +185,24 @@ module Aromancer
186
185
  end
187
186
  end
188
187
 
189
- def self.create_turn(arena_params)
190
- result = Aromancer::Server.create_turn({arena: arena_params})
191
- if result.status == 201
188
+ def self.submit_turn(request_uuid, option = {})
189
+ result = Aromancer::Server.submit_turn(request_uuid, option)
190
+ if result.status == 200
192
191
  response = JSON.parse(result.body)
192
+ Aromancer::Storage.set_arena(response)
193
193
  else
194
194
  register_error(result)
195
195
  end
196
196
  end
197
197
 
198
- def self.update_turn(arena_params)
199
- result = Aromancer::Server.update_turn({arena: arena_params})
198
+ def self.load_rules
199
+ result = Aromancer::Server.load_rules
200
200
  if result.status == 200
201
- response = JSON.parse(result.body)
201
+ return JSON.parse(result.body)
202
202
  else
203
203
  register_error(result)
204
204
  end
205
205
  end
206
-
207
206
  end
208
207
 
209
208
  end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ =begin
4
+
5
+ cli.rb
6
+
7
+ aromancer cli
8
+
9
+ by i2097i
10
+
11
+ =end
12
+
13
+ module Aromancer
14
+ # instance runs on main thread
15
+ class Cli
16
+ include Singleton
17
+
18
+ attr_accessor :ui_thread, :ws_thread, :ui_busy, :ws_busy, :last_render, :error_timeout
19
+
20
+ THROTTLE_MS = 0.1
21
+
22
+ # user entry point
23
+ def self.run
24
+ Aromancer::Websocket.instance
25
+ Aromancer::Storage.instance
26
+
27
+ self.instance.last_render = 0
28
+ self.instance.error_timeout = Time.now.to_i
29
+
30
+ # load player on-start
31
+ Aromancer::Api.set_active_legend_id(nil) unless Aromancer::Storage.get_player.nil?
32
+
33
+ Thread.main[:route] = :authentication
34
+ Thread.main[:menu_runners] = {}
35
+ Thread.main[:menu_options] = {}
36
+ Aromancer::Prompt.say(I18n.t("shared.welcome", version: Aromancer::VERSION))
37
+ Aromancer::Prompt.say(I18n.t("shared.server_url", url: Aromancer::Storage::get_server_url))
38
+ self.instance.start_ui_thread
39
+ self.instance.start_ws_thread
40
+ loop do
41
+ begin
42
+ self.instance.ui_thread.join
43
+ rescue NoMethodError => e
44
+ if Aromancer::Storage.get_preference(:debug)
45
+ Aromancer::Prompt.say(I18n.t("shared.last_error"))
46
+ Aromancer::Prompt.say(JSON.pretty_generate(e[:body.to_s]))
47
+ Aromancer::Prompt.say("sleeping 5 on main thread...")
48
+ sleep(5)
49
+ end
50
+ self.instance.start_ui_thread
51
+ self.instance.start_ws_thread
52
+ sleep(1)
53
+ rescue Interrupt => e
54
+ Aromancer::Prompt.say("interrupt on main thread...exiting immediately.")
55
+ exit
56
+ end
57
+ end
58
+ end
59
+
60
+ def start_ui_thread(force = false)
61
+ return if (@ui_busy || Time.now - @last_render < 2.0) && !force
62
+
63
+ @ui_busy = true
64
+ self.ui_thread&.exit
65
+ self.ui_thread&.kill
66
+ Thread.main[:menu_runners] = {}
67
+ Thread.main[:menu_options] = {}
68
+ Aromancer::Prompt.instance.reload!
69
+ self.ui_thread = Thread.new do
70
+ loop do
71
+ menu_options = Thread.main[:menu_options][Thread.main[:route]]
72
+ menu_runners = Thread.main[:menu_runners][Thread.main[:route]]
73
+ unless menu_options.nil? ||
74
+ menu_runners.nil? ||
75
+ menu_options.empty? ||
76
+ menu_runners.empty?
77
+
78
+ Aromancer::Routes.resume
79
+ sleep(THROTTLE_MS)
80
+ Aromancer.print_hud
81
+
82
+ v = Aromancer::Prompt.p.select("", menu_options, show_help: :always, cycle: true, per_page: 11)
83
+ Aromancer.print_hud
84
+ runners = menu_runners.select{|r| r[:value] == v}
85
+ runners = menu_runners.select{|r| r[:value].nil?} if runners.empty?
86
+
87
+ if runners.any?
88
+ r = runners.first
89
+ r[:proc].call(v)
90
+ end
91
+
92
+ else
93
+ sleep(THROTTLE_MS)
94
+ Aromancer::Routes.resume
95
+ end
96
+ Aromancer::Cli.instance.ui_busy = false
97
+ Aromancer::Cli.instance.last_render = Time.now
98
+ sleep(THROTTLE_MS)
99
+ end
100
+ end
101
+ end
102
+
103
+ def start_ws_thread
104
+ return if @ws_busy
105
+ @ws_busy = true
106
+ self.ws_thread&.exit
107
+ self.ws_thread&.kill
108
+ self.ws_thread = Thread.new do
109
+ Aromancer::Websocket.instance.disconnect
110
+ loop do
111
+ player = Aromancer::Storage.get_player
112
+ if player.nil? ||
113
+ player["active_legend_id"].nil?
114
+ @ws_busy = true
115
+ Aromancer::Websocket.instance.disconnect
116
+ elsif !player["api_key"].nil? &&
117
+ !player["active_legend_id"].nil? &&
118
+ (Aromancer::Websocket.instance.socket.nil? || Aromancer::Websocket.instance.socket.closed?)
119
+ # attempt websocket connection
120
+ @ws_busy = true
121
+ Aromancer::Websocket.instance.connect
122
+ if Aromancer::Storage.get_arena.nil?
123
+ Aromancer::Api.load_arena
124
+ sleep(1)
125
+ Aromancer::Cli.instance.start_ui_thread(true)
126
+ end
127
+ end
128
+ @ws_busy = false
129
+ sleep(1)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -28,8 +28,24 @@ module Aromancer
28
28
  Aromancer::Prompt.instance.prompt
29
29
  end
30
30
 
31
- def self.say(message)
32
- (message.kind_of?(String) ? message.split("\n").each{|l| p.say(l.to_s.center(TTY::Screen.width))} : message)
31
+ def self.print_divider(text = nil)
32
+ puts "\n" if TTY::Screen.width > 99.9
33
+ self.p.say((text || "").center(TTY::Screen.width / 2.2, "-").center(TTY::Screen.width))
34
+ puts "\n" if TTY::Screen.width > 99.9
35
+ end
36
+
37
+ def self.say(message, ljust: false, rjust: false)
38
+ center = !ljust && !rjust
39
+ if message.kind_of?(String)
40
+ # puts "\n" if TTY::Screen.width > 99.9
41
+ message.split("\n").each{|l|
42
+ self.p.say(l.to_s.ljust(TTY::Screen.width)) if ljust
43
+ self.p.say(l.to_s.center(TTY::Screen.width)) if center
44
+ self.p.say(l.to_s.rjust(TTY::Screen.width)) if rjust
45
+ }
46
+ else
47
+ self.p.say(message)
48
+ end
33
49
  end
34
50
  end
35
51