Skip to content

Commit 811401f

Browse files
committed
Add support for 3 new game events - CityFounded, WarDeclared and CityConquered.
1 parent 5429dce commit 811401f

11 files changed

Lines changed: 179 additions & 5 deletions

File tree

app/models/pitboss_entry.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,21 @@ def entry_to_domain_event
3535
Game::TimerReset.new(data: { slot: value.to_i, game_id: game_name }),
3636
stream_name: "Game$#{game_name}"
3737
)
38+
when "CityFounded"
39+
event_store.publish(
40+
Game::CityFounded.new(data: { slot: value.to_i, game_id: game_name }),
41+
stream_name: "Game$#{game_name}"
42+
)
43+
when "WarDeclared"
44+
event_store.publish(
45+
Game::WarDeclared.new(data: { slot: value.to_i, game_id: game_name }),
46+
stream_name: "Game$#{game_name}"
47+
)
48+
when "CityConquered"
49+
event_store.publish(
50+
Game::CityConquered.new(data: { slot: value.to_i, game_id: game_name }),
51+
stream_name: "Game$#{game_name}"
52+
)
3853
end
3954
end
4055
end

config/initializers/rails_event_store.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
.new(logger: Rails.logger, event_store: Rails.configuration.event_store)
2727
.call(event)
2828
end,
29-
to: [Game::NewTurnStarted, Game::PlayerDisconnected, Game::TimerReset]
29+
to: [Game::NewTurnStarted, Game::PlayerDisconnected, Game::TimerReset, Game::CityFounded, Game::WarDeclared, Game::CityConquered]
3030
)
3131
client.subscribe(
3232
-> (event) do

game/lib/game.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ module Game
1111
PlayerUnregistered = Class.new(DomainEvent)
1212
PlayerSlotfhulnessIncreased = Class.new(DomainEvent)
1313
TimerReset = Class.new(DomainEvent)
14+
CityFounded = Class.new(DomainEvent)
15+
WarDeclared = Class.new(DomainEvent)
16+
CityConquered = Class.new(DomainEvent)
1417

1518
HostGame = Struct.new(:game_id, :turn_timer)
1619
RegisterPlayer = Struct.new(:game_id, :player_id, :slot_id)

game/spec/spec_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def event_store
1717
)
1818
client.subscribe(
1919
-> (event) { Notifications::SlackNotifier.new(logger: Rails.logger, event_store: client).call(event) },
20-
to: [Game::NewTurnStarted, Game::PlayerDisconnected]
20+
to: [Game::NewTurnStarted, Game::PlayerDisconnected, Game::CityFounded, Game::WarDeclared, Game::CityConquered]
2121
)
2222
end
2323
end

logs_parser/lib/logs_parser.rb

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ def call(line)
3232
elsif timer_reset?(line)
3333
player_number = line.scan(/\d/)[-3]
3434
return Result.new(game_name, "TimerReset", player_number, timestamp)
35+
elsif city_founded?(line)
36+
player_number = line.match(/who is (\d+)/)[1]
37+
return Result.new(game_name, "CityFounded", player_number, timestamp)
38+
elsif war_declared?(line)
39+
player_number = line.match(/Net RECV \((\d+)\)/)[1]
40+
return Result.new(game_name, "WarDeclared", player_number, timestamp)
41+
elsif city_conquered?(line)
42+
player_number = line.match(/Net RECV \((\d+)\)/)[1]
43+
return Result.new(game_name, "CityConquered", player_number, timestamp)
3544
end
3645
end
3746
end
@@ -42,7 +51,9 @@ def call(line)
4251

4352
def contains_relevant_data?(line)
4453
line.match(/DBG: Game Turn/) || line.match(/:NetTurnComplete/) || line.match(/NetTurnUnready/) ||
45-
line.match(/NetPlayerReady/) || line.match(/ConnectionClosed Player\(\d\)/) || line.match(/:NetGiftUnit.+UnitID=-1/)
54+
line.match(/NetPlayerReady/) || line.match(/ConnectionClosed Player\(\d\)/) || line.match(/:NetGiftUnit.+UnitID=-1/) ||
55+
line.match(/mission is Found City/) || line.match(/:NetChangeWar/) ||
56+
line.match(/TASK_CREATE_PUPPET|TASK_ANNEX|TASK_RAZE/)
4657
end
4758

4859
def split_log_line(line)
@@ -74,6 +85,18 @@ def player_disconnected?(line)
7485
def timer_reset?(line)
7586
line.match(/:NetGiftUnit.+UnitID=-1/)
7687
end
88+
89+
def city_founded?(line)
90+
line.match(/mission is Found City/)
91+
end
92+
93+
def war_declared?(line)
94+
line.match(/:NetChangeWar/)
95+
end
96+
97+
def city_conquered?(line)
98+
line.match(/TASK_CREATE_PUPPET|TASK_ANNEX|TASK_RAZE/)
99+
end
77100
end
78101

79102
class HttpAdapter

logs_parser/spec/service_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,42 @@
8585
expect_result(result, game_name: "arkency_test", entry_type: "TimerReset", data: "1", timestamp: "3540015.559")
8686
end
8787

88+
specify "city founded" do
89+
parser = LogsParser::Service.new("arkency_test", 6)
90+
result = parser.call("[672732.150] Net RECV (0) :NetPushMission : Do Mission, who is 0, unit ID is 8192 (Settler), mission is Found City, data1=-1, data2=-1, shift=false\n")
91+
expect_result(result, game_name: "arkency_test", entry_type: "CityFounded", data: "0", timestamp: "672732.150")
92+
end
93+
94+
specify "city founded ignores settler move" do
95+
parser = LogsParser::Service.new("arkency_test", 6)
96+
result = parser.call("[672732.150] Net RECV (0) :NetPushMission : Do Mission, who is 0, unit ID is 8192 (Settler), mission is Move, data1=41, data2=32, shift=false\n")
97+
expect(result).to be_nil
98+
end
99+
100+
specify "war declared" do
101+
parser = LogsParser::Service.new("arkency_test", 6)
102+
result = parser.call("[674000.151] Net RECV (0) :NetChangeWar : Change War, rival team is 33\n")
103+
expect_result(result, game_name: "arkency_test", entry_type: "WarDeclared", data: "0", timestamp: "674000.151")
104+
end
105+
106+
specify "city conquered via puppet" do
107+
parser = LogsParser::Service.new("arkency_test", 6)
108+
result = parser.call("[674043.151] Net RECV (0) :NetDoTask : City ID 16385 (TXT_KEY_CITYSTATE_KUWAIT), doing task 19 (TASK_CREATE_PUPPET), data1 -1, data2 -1\n")
109+
expect_result(result, game_name: "arkency_test", entry_type: "CityConquered", data: "0", timestamp: "674043.151")
110+
end
111+
112+
specify "city conquered via annex" do
113+
parser = LogsParser::Service.new("arkency_test", 6)
114+
result = parser.call("[674043.151] Net RECV (0) :NetDoTask : City ID 16385 (TXT_KEY_CITY_NAME_WARSAW), doing task 20 (TASK_ANNEX), data1 -1, data2 -1\n")
115+
expect_result(result, game_name: "arkency_test", entry_type: "CityConquered", data: "0", timestamp: "674043.151")
116+
end
117+
118+
specify "city conquered via raze" do
119+
parser = LogsParser::Service.new("arkency_test", 6)
120+
result = parser.call("[674043.151] Net RECV (0) :NetDoTask : City ID 16385 (TXT_KEY_CITY_NAME_BERLIN), doing task 21 (TASK_RAZE), data1 -1, data2 -1\n")
121+
expect_result(result, game_name: "arkency_test", entry_type: "CityConquered", data: "0", timestamp: "674043.151")
122+
end
123+
88124
private
89125

90126
def expect_result(result, game_name:, entry_type:, data:, timestamp:)

notifications/lib/notifications/slack_notifier.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ def call(event)
1515
maybe_notify_remaining_players(event)
1616
when Game::TimerReset
1717
notify_about_timer_reset(event)
18+
when Game::CityFounded
19+
notify_game_event(event, "A new city has been founded in far away land")
20+
when Game::WarDeclared
21+
notify_game_event(event, "A war has been declared in far away land")
22+
when Game::CityConquered
23+
notify_game_event(event, "A city has been conquered in far away land")
1824
end
1925
rescue => e
2026
error_message = "Error in Notifications::SlackNotifier: #{e.inspect}"
@@ -62,6 +68,16 @@ def notify_about_timer_reset(event)
6268
)
6369
end
6470

71+
def notify_game_event(event, message)
72+
game = ReadModel::GameReadModel.find_by(id: event.data[:game_id])
73+
return unless game && game.slack_token
74+
CustomSlackClient.post_message(
75+
channel: game.slack_channel,
76+
text: message,
77+
token: game.slack_token
78+
)
79+
end
80+
6581
attr_reader :logger, :event_store
6682
end
6783
end

notifications/spec/notifications/slack_notifier_spec.rb

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,69 @@ def given(*domain_events)
155155
expect(stub1).to have_been_requested
156156
end
157157

158+
specify("city founded notification") do
159+
game_read_model
160+
event = Game::CityFounded.new(data: {slot: 0, game_id: game_id})
161+
stub = stub_request(:post, "https://slack.com/api/chat.postMessage")
162+
.with(
163+
body: {
164+
"channel" => "#arkency58",
165+
"text" => "A new city has been founded in far away land"
166+
},
167+
headers: {
168+
"Authorization" => "Bearer xoxb-302139800755-nR1O848GLyVS5ZfNNMpBLm0b",
169+
"Accept" => "application/json; charset=utf-8",
170+
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
171+
"Content-Type" => "application/json"
172+
}
173+
)
174+
.to_return(status: 200, body: {ok: true}.to_json, headers: {})
175+
event_store.publish(event, stream_name: game_id)
176+
expect(stub).to have_been_requested
177+
end
178+
179+
specify("war declared notification") do
180+
game_read_model
181+
event = Game::WarDeclared.new(data: {slot: 0, game_id: game_id})
182+
stub = stub_request(:post, "https://slack.com/api/chat.postMessage")
183+
.with(
184+
body: {
185+
"channel" => "#arkency58",
186+
"text" => "A war has been declared in far away land"
187+
},
188+
headers: {
189+
"Authorization" => "Bearer xoxb-302139800755-nR1O848GLyVS5ZfNNMpBLm0b",
190+
"Accept" => "application/json; charset=utf-8",
191+
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
192+
"Content-Type" => "application/json"
193+
}
194+
)
195+
.to_return(status: 200, body: {ok: true}.to_json, headers: {})
196+
event_store.publish(event, stream_name: game_id)
197+
expect(stub).to have_been_requested
198+
end
199+
200+
specify("city conquered notification") do
201+
game_read_model
202+
event = Game::CityConquered.new(data: {slot: 0, game_id: game_id})
203+
stub = stub_request(:post, "https://slack.com/api/chat.postMessage")
204+
.with(
205+
body: {
206+
"channel" => "#arkency58",
207+
"text" => "A city has been conquered in far away land"
208+
},
209+
headers: {
210+
"Authorization" => "Bearer xoxb-302139800755-nR1O848GLyVS5ZfNNMpBLm0b",
211+
"Accept" => "application/json; charset=utf-8",
212+
"Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
213+
"Content-Type" => "application/json"
214+
}
215+
)
216+
.to_return(status: 200, body: {ok: true}.to_json, headers: {})
217+
event_store.publish(event, stream_name: game_id)
218+
expect(stub).to have_been_requested
219+
end
220+
158221
specify("timer reset notification") do
159222
player_1 = Player.create!(steam_name: "some_player", slack_name: "slack_user")
160223
game = game_read_model

notifications/spec/spec_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def event_store
1717
.tap do |client|
1818
client.subscribe(
1919
->(event) { Notifications::SlackNotifier.new(logger: Rails.logger, event_store: client).call(event) },
20-
to: [Game::NewTurnStarted, Game::PlayerDisconnected, Game::TimerReset]
20+
to: [Game::NewTurnStarted, Game::PlayerDisconnected, Game::TimerReset, Game::CityFounded, Game::WarDeclared, Game::CityConquered]
2121
)
2222
client.subscribe(
2323
->(event) { ReadModel::GameReadModelUpdater.new(logger: Rails.logger).call(event) },

spec/domain_events_from_entries_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,22 @@ def event_store
5252

5353
expect(event_store).to(have_published(an_event(Game::TimerReset).with_data(slot: 5, game_id: "dummy")))
5454
end
55+
56+
specify("CityFounded") do
57+
PitbossEntry.create(timestamp: 0, value: 0, entry_type: "CityFounded", game_name: "dummy")
58+
59+
expect(event_store).to(have_published(an_event(Game::CityFounded).with_data(slot: 0, game_id: "dummy")))
60+
end
61+
62+
specify("WarDeclared") do
63+
PitbossEntry.create(timestamp: 0, value: 0, entry_type: "WarDeclared", game_name: "dummy")
64+
65+
expect(event_store).to(have_published(an_event(Game::WarDeclared).with_data(slot: 0, game_id: "dummy")))
66+
end
67+
68+
specify("CityConquered") do
69+
PitbossEntry.create(timestamp: 0, value: 0, entry_type: "CityConquered", game_name: "dummy")
70+
71+
expect(event_store).to(have_published(an_event(Game::CityConquered).with_data(slot: 0, game_id: "dummy")))
72+
end
5573
end

0 commit comments

Comments
 (0)