New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session registry keeps a simple version of the character data #73

Merged
merged 2 commits into from Aug 26, 2018
Jump to file or symbol
Failed to load files and symbols.
+101 −63
Diff settings

Always

Just for now

@@ -0,0 +1,26 @@
defmodule Game.Character.Simple do
@moduledoc """
Simple version of a character
Minimal data for accessing the full character
"""
defstruct [:type, :id, :name, extra: %{}]
@doc """
Convert a user to the simple version
"""
def from_user(user) do
%__MODULE__{
type: :user,
id: user.id,
name: user.name,
extra: %{
flags: user.flags,
level: user.save.level,
race: user.race.name,
class: user.class.name,
}
}
end
end
View
@@ -50,7 +50,7 @@ defmodule Game.Command.Who do
defp local_names(players) do
{admins, players} =
Enum.split_with(players, fn %{user: user} ->
User.is_admin?(user)
User.is_admin?(user.extra)
end)
(admins ++ players)
View
@@ -12,7 +12,7 @@ defmodule Game.Format.Who do
[
player_stats(player),
Format.player_name(player),
Format.player_flags(player, none: false),
Format.player_flags(player.extra, none: false),
afk(metadata)
]
|> Enum.join(" ")
@@ -30,9 +30,9 @@ defmodule Game.Format.Who do
defp player_stats(player) do
Enum.join([
"[",
String.pad_leading(Integer.to_string(player.save.level), 3),
pad_and_limit(player.class.name),
pad_and_limit(player.race.name),
String.pad_leading(Integer.to_string(player.extra.level), 3),
pad_and_limit(player.extra.class),
pad_and_limit(player.extra.race),
"]"
])
end
@@ -62,8 +62,10 @@ defmodule Game.Session.Registry do
def register(user) do
members = :pg2.get_members(@key)
character = Character.Simple.from_user(user)
Enum.map(members, fn member ->
GenServer.cast(member, {:register, self(), user, %Metadata{is_afk: false}})
GenServer.cast(member, {:register, self(), character, %Metadata{is_afk: false}})
end)
end
@@ -74,8 +76,10 @@ defmodule Game.Session.Registry do
def update(user, state) do
members = :pg2.get_members(@key)
character = Character.Simple.from_user(user)
Enum.map(members, fn member ->
GenServer.cast(member, {:update, self(), user, %Metadata{is_afk: state.is_afk}})
GenServer.cast(member, {:update, self(), character, %Metadata{is_afk: state.is_afk}})
end)
end
@@ -79,7 +79,7 @@ defmodule Metrics.PlayerInstrumenter do
"""
@spec set_player_count(list) :: list
def set_player_count(players) do
{admins, players} = Enum.split_with(players, &("admin" in &1.flags))
{admins, players} = Enum.split_with(players, &("admin" in &1.extra.flags))
Gauge.set([name: :exventure_player_count, labels: [:players]], length(players))
Gauge.set([name: :exventure_player_count, labels: [:admins]], length(admins))
end
@@ -83,7 +83,6 @@
<%= Enum.map(@players, fn (player) -> %>
<li class="list-group-item">
<%= link(player.name, to: user_path(@conn, :show, player.id)) %>
<%= link("Teleport to", to: user_path(@conn, :teleport, room_id: player.save.room_id), method: "post", class: "pull-right") %>
</li>
<% end) %>
</ul>
@@ -59,22 +59,6 @@
</table>
</div>
</div>
<%= if online?(@user) do %>
<div class="box">
<div class="box-header">
<h3 class="box-title">Live Stats</h3>
</div>
<div class="box-body">
<table class="table">
<tr>
<th>Room</th>
<td><%= link(live(@user).save.room_id, to: room_path(@conn, :show, live(@user).save.room_id)) %></td>
</tr>
</table>
</div>
</div>
<% end %>
</div>
<div class="col-md-6">
@@ -14,10 +14,6 @@ defmodule Web.Admin.UserView do
Enum.any?(User.connected_players(), &(&1.id == user.id))
end
def live(user) do
Enum.find(User.connected_players(), &(&1.id == user.id))
end
def stat_display_name(stat) do
stat
|> to_string()
@@ -24,7 +24,7 @@ defmodule Game.Command.MoveTest do
start_and_clear_doors()
socket = :socket
user = %{id: 10}
user = base_user()
state = %State{
state: "active",
mode: "command",
@@ -28,7 +28,7 @@ defmodule Game.Command.SkillsTest do
npc = %{id: 1, name: "Bandit"}
save = %{base_save() | level: 1, stats: %{health_points: 20, strength: 10, skill_points: 10}, wearing: %{}, skill_ids: [slash.id]}
user = %{id: 10, name: "Player", save: save}
user = %{base_user() | save: save}
room =
@room._room()
@@ -14,7 +14,7 @@ defmodule Game.Command.TellTest do
setup do
@socket.clear_messages
@room.set_room(Map.merge(@room._room(), %{npcs: []}))
user = %{id: 10, name: "Player"}
user = base_user()
state = %State{socket: :socket, state: "active", mode: "commands", user: user, save: %{room_id: 1}}
%{state: state}
end
@@ -35,7 +35,9 @@ defmodule Game.Command.UseTest do
base_save()
|> Map.put(:items, [%Item.Instance{id: 1, created_at: Timex.now(), amount: 1}])
%{socket: :socket, user: %{id: 1, name: "Player"}, save: save}
user = %{base_user() | id: 1, save: save}
%{socket: :socket, user: user, save: user.save}
end
test "use an item - removes if amount ends up as 0", state = %{socket: socket} do
@@ -28,7 +28,7 @@ defmodule Game.NPC.EventsTest do
describe "character/died" do
setup do
npc = %{id: 1, name: "Mayor", events: [], stats: base_stats()}
user = %{id: 2, name: "Player"}
user = %{base_user() | id: 2}
state = %State{room_id: 1, npc: npc, target: nil}
@@ -108,7 +108,8 @@ defmodule Game.NPC.EventsTest do
end
test "calculates the effects and then applies them to the target", %{state: state, event: event} do
Registry.register(%{id: 1})
notify_user = %{base_user() | id: 1}
Registry.register(notify_user)
state = %State{state | target: {:user, 1}}
{:update, state} = Events.act_on(state, event)
@@ -149,42 +150,45 @@ defmodule Game.NPC.EventsTest do
end
test "target the player when they entered" do
Registry.register(%{id: 2})
notify_user = %{base_user() | id: 2}
Registry.register(notify_user)
npc = %{id: 1, name: "Mayor", events: [%{type: "room/entered", action: %{type: "target"}}]}
state = %State{room_id: 1, npc: npc}
{:update, state} = Events.act_on(state, {"room/entered", {{:user, %{id: 2, name: "Player"}}, :enter}})
{:update, state} = Events.act_on(state, {"room/entered", {{:user, notify_user}, :enter}})
assert state.target == {:user, 2}
assert_received {:"$gen_cast", {:targeted, {:npc, %{id: 1}}}}
end
test "target the player when they entered - target if target is nil and in combat" do
Registry.register(%{id: 2})
notify_user = %{base_user() | id: 2}
Registry.register(notify_user)
npc = %{id: 1, name: "Mayor", events: [%{type: "room/entered", action: %{type: "target"}}]}
state = %State{room_id: 1, npc: npc, combat: true, target: nil}
{:update, state} = Events.act_on(state, {"room/entered", {{:user, %{id: 2, name: "Player"}}, :enter}})
{:update, state} = Events.act_on(state, {"room/entered", {{:user, notify_user}, :enter}})
assert state.target == {:user, 2}
assert_received {:"$gen_cast", {:targeted, {:npc, %{id: 1}}}}
end
test "target the player when they entered - do nothing if already in combat" do
Registry.register(%{id: 2})
notify_user = %{base_user() | id: 2}
Registry.register(notify_user)
npc = %{id: 1, name: "Mayor", events: [%{type: "room/entered", action: %{type: "target"}}]}
state = %State{room_id: 1, npc: npc}
{:update, state} = Events.act_on(state, {"room/entered", {{:user, %{id: 2, name: "Player"}}, :enter}})
{:update, state} = Events.act_on(state, {"room/entered", {{:user, notify_user}, :enter}})
assert state.target == {:user, 2}
assert state.combat == true
assert_received {:"$gen_cast", {:targeted, {:npc, %{id: 1}}}}
{:update, state} = Events.act_on(state, {"room/entered", {{:user, %{id: 2, name: "Player"}}, :enter}})
{:update, state} = Events.act_on(state, {"room/entered", {{:user, notify_user}, :enter}})
assert state.target == {:user, 2}
refute_received {:"$gen_cast", {:targeted, {:npc, %{id: 1}}}}
@@ -13,7 +13,7 @@ defmodule Game.Overworld.SectorTest do
npcs: [],
}
user = %User{id: 10, name: "Player"}
user = base_user()
npc = %{id: 11, name: "Bandit"}
%{state: state, user: user, npc: npc, overworld_id: "1:1,1"}
@@ -45,7 +45,7 @@ defmodule Game.Overworld.SectorTest do
end
test "sends a notification to users in the same cell", %{state: state, user: user, overworld_id: overworld_id} do
notify_user = %User{id: 11}
notify_user = %{base_user() | id: 11}
Session.Registry.register(notify_user)
state = %{state | players: [{%{x: 1, y: 1}, notify_user}]}
@@ -56,7 +56,7 @@ defmodule Game.Overworld.SectorTest do
end
test "does not send notifications to users in different cells", %{state: state, user: user, overworld_id: overworld_id} do
notify_user = %User{id: 11}
notify_user = %{base_user() | id: 11}
Session.Registry.register(notify_user)
state = %{state | players: [{%{x: 1, y: 2}, notify_user}]}
@@ -85,7 +85,7 @@ defmodule Game.Overworld.SectorTest do
end
test "sends a notification to users in the same cell", %{state: state, user: user, overworld_id: overworld_id} do
notify_user = %User{id: 11}
notify_user = %{base_user() | id: 11}
Session.Registry.register(notify_user)
state = %{state | players: [{%{x: 1, y: 1}, user}, {%{x: 1, y: 1}, notify_user}]}
@@ -96,7 +96,7 @@ defmodule Game.Overworld.SectorTest do
end
test "does not send notifications to users in different cells", %{state: state, user: user, overworld_id: overworld_id} do
notify_user = %User{id: 11}
notify_user = %{base_user() | id: 11}
Session.Registry.register(notify_user)
state = %{state | players: [{%{x: 1, y: 1}, user}, {%{x: 1, y: 2}, notify_user}]}
@@ -109,7 +109,7 @@ defmodule Game.Overworld.SectorTest do
describe "notify" do
test "sends notifications to players in the same cell", %{state: state, user: user, overworld_id: overworld_id} do
notify_user = %User{id: 11}
notify_user = %{base_user() | id: 11}
Session.Registry.register(notify_user)
state = %{state | players: [{%{x: 1, y: 1}, user}, {%{x: 1, y: 1}, notify_user}]}
@@ -120,7 +120,7 @@ defmodule Game.Overworld.SectorTest do
end
test "does not send notifications to users in different cells", %{state: state, user: user, overworld_id: overworld_id} do
notify_user = %User{id: 11}
notify_user = %{base_user() | id: 11}
Session.Registry.register(notify_user)
state = %{state | players: [{%{x: 1, y: 1}, user}, {%{x: 1, y: 2}, notify_user}]}
@@ -133,7 +133,7 @@ defmodule Game.Overworld.SectorTest do
describe "say" do
test "sends a say message", %{state: state, user: user, overworld_id: overworld_id} do
notify_user = %User{id: 11}
notify_user = %{base_user() | id: 11}
Session.Registry.register(notify_user)
state = %{state | players: [{%{x: 1, y: 1}, user}, {%{x: 1, y: 1}, notify_user}]}
@@ -146,7 +146,7 @@ defmodule Game.Overworld.SectorTest do
describe "emote" do
test "sends an emote message", %{state: state, user: user, overworld_id: overworld_id} do
notify_user = %User{id: 11}
notify_user = %{base_user() | id: 11}
Session.Registry.register(notify_user)
state = %{state | players: [{%{x: 1, y: 1}, user}, {%{x: 1, y: 1}, notify_user}]}
@@ -29,6 +29,7 @@ defmodule Game.Session.LoginTest do
test "a session already exists", %{socket: socket} do
user = create_user(%{name: "user", password: "password", class_id: create_class().id})
user = Repo.preload(user, [:race, :class])
Registry.register(user)
state = Login.sign_in(user.id, %{socket: socket, login: %{name: "user"}})
@@ -5,7 +5,7 @@ defmodule Game.Session.RegistryTest do
describe "online/offline" do
test "receive a notification for offline" do
Registry.register(%{id: 1, name: "Player 1"})
Registry.register(base_user())
Registry.player_offline(%{id: 2, name: "Player 2"})
@@ -15,7 +15,7 @@ defmodule Game.Session.RegistryTest do
end
test "receive a notification for online" do
Registry.register(%{id: 1, name: "Player 1"})
Registry.register(base_user())
Registry.player_online(%{id: 2, name: "Player 2"})
Oops, something went wrong.
ProTip! Use n and p to navigate between commits in a pull request.