Skip to content
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

Game.management #23

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ce17cc2
initial pass at schemas for game/character.
matthewphilyaw Feb 3, 2016
2094204
remove has many relationship out of game and for now out of user
matthewphilyaw Feb 3, 2016
178c296
remove tests for game and character for the moment.
matthewphilyaw Feb 3, 2016
202b05a
added unique constraints to character for so that only one character …
matthewphilyaw Feb 3, 2016
d1b1310
adding tests for the new models
matthewphilyaw Feb 6, 2016
6a12c6e
removed model helper, drags coverage down and not being used.
matthewphilyaw Feb 6, 2016
d33a8bf
added two more cases for required fields and now have a propper setup…
matthewphilyaw Feb 12, 2016
141f7e3
update dir structure.
matthewphilyaw Feb 21, 2016
3773bfc
removed ecto.query
matthewphilyaw Feb 21, 2016
45fedea
rename user_id to char_id in player modules
matthewphilyaw Feb 12, 2016
28f5850
changer user key to character.
matthewphilyaw Feb 12, 2016
6e42e4d
renamed mon2user functions to mon2character.
matthewphilyaw Feb 12, 2016
deadd4d
added game controller and view
matthewphilyaw Feb 16, 2016
5447bcc
super basic game controller tests to get started with
matthewphilyaw Feb 17, 2016
945463e
had one unused variable, and removed IEx.pry calls
matthewphilyaw Feb 17, 2016
64db24b
character controller roughed out.
matthewphilyaw Feb 17, 2016
13e508d
controllers updated to match app structure.
matthewphilyaw Feb 21, 2016
5c12d97
added the start of character controller tests.
matthewphilyaw Feb 21, 2016
ad49fe6
bump guardian version
matthewphilyaw Feb 21, 2016
57734d6
Load user via Guardian.Plug.LoadResource on each request
matthewphilyaw Feb 21, 2016
c475275
add controller tests, which also needed a character_view module
matthewphilyaw Feb 21, 2016
5383601
added coverage for create/delete and ensured the others tests fulfill…
matthewphilyaw Feb 22, 2016
7ecac4e
more tests to ensure a character can only be created for a given user…
matthewphilyaw Feb 23, 2016
f595d80
Char.perms
matthewphilyaw Apr 2, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.swp
/_build
/cover
apps/*/cover
Expand Down
30 changes: 30 additions & 0 deletions apps/yggdrasil/lib/yggdrasil/character.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule Yggdrasil.Character do
use Ecto.Schema
import Ecto.Changeset

schema "characters" do
field :name, :string
belongs_to :user, Yggdrasil.User
belongs_to :game, Yggdrasil.Game

timestamps
end

@required_fields ~w(name user_id game_id)
@optional_fields ~w()

@doc """
Creates a changeset based on the `model` and `params`.

If no params are provided, an invalid changeset is returned
with no validation performed.
"""
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> unique_constraint(:name, name: :characters_name_game_id_index)
|> assoc_constraint(:user)
|> assoc_constraint(:game)
|> validate_length(:name, min: 3)
end
end
28 changes: 28 additions & 0 deletions apps/yggdrasil/lib/yggdrasil/game.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule Yggdrasil.Game do
use Ecto.Schema
import Ecto.Changeset

schema "games" do
field :name, :string
field :description, :string

timestamps
end

@required_fields ~w(name description)
@optional_fields ~w()

@doc """
Creates a changeset based on the `model` and `params`.

If no params are provided, an invalid changeset is returned
with no validation performed.
"""
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> unique_constraint(:name)
|> validate_length(:name, min: 3)
|> validate_length(:description, min: 3)
end
end
8 changes: 8 additions & 0 deletions apps/yggdrasil/lib/yggdrasil/permission.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule Yggdrasil.Permission do
use Ecto.Schema

@primary_key {:name, :string, []}
schema "permissions" do
timestamps
end
end
22 changes: 11 additions & 11 deletions apps/yggdrasil/lib/yggdrasil/player.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ defmodule Yggdrasil.Player do
alias Yggdrasil.Player.Registry
alias Yggdrasil.Command

def start_link(user_id, owner_pid, push_msg) do
GenServer.start_link __MODULE__, [user_id, owner_pid, push_msg]
def start_link(char_id, owner_pid, push_msg) do
GenServer.start_link __MODULE__, [char_id, owner_pid, push_msg]
end

def join_game(user_id, owner_pid, push_msg) do
Supervisor.add_player user_id, [owner_pid, push_msg]
def join_game(char_id, owner_pid, push_msg) do
Supervisor.add_player char_id, [owner_pid, push_msg]
end

def run_cmd(user_id, cmd) do
def run_cmd(char_id, cmd) do
# horrible terrible temporary implementation
# room would eventually do all of this
ctxt = %Yggdrasil.Room.Context{ player: user_id }
ctxt = %Yggdrasil.Room.Context{ player: char_id }
ctxt = Command.execute cmd, ctxt

Enum.each ctxt.actions,
Expand All @@ -25,19 +25,19 @@ defmodule Yggdrasil.Player do
end
end

def notify(user_id, msg = %Message{}) do
player_pid = Registry.get_player user_id
def notify(char_id, msg = %Message{}) do
player_pid = Registry.get_player char_id
GenServer.cast(player_pid, {:notify, msg})
end


def init([user_id, channel_pid, push_msg]) do
case Registry.register_player(user_id, self) do
def init([char_id, channel_pid, push_msg]) do
case Registry.register_player(char_id, self) do
:ok ->
monitor_ref = Process.monitor channel_pid
push_msg.(Message.info("Welcome to the game"))
{:ok, %{
user: user_id,
character: char_id,
channel: channel_pid,
monitor: monitor_ref,
push_msg: push_msg
Expand Down
60 changes: 30 additions & 30 deletions apps/yggdrasil/lib/yggdrasil/player/registry.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@ defmodule Yggdrasil.Player.Registry do
GenServer.start_link __MODULE__, [], name: __MODULE__
end

def register_player(user_id, player_pid) do
GenServer.call __MODULE__, {:register, user_id, player_pid}
def register_player(char_id, player_pid) do
GenServer.call __MODULE__, {:register, char_id, player_pid}
end

def is_online(user_id, options \\ [])
def is_online(user_id, options) do
def is_online(char_id, options \\ [])
def is_online(char_id, options) do
sync = Keyword.get(options, :sync, false)

if sync do
GenServer.call __MODULE__, {:is_online, user_id}
GenServer.call __MODULE__, {:is_online, char_id}
else
do_is_online user_id
do_is_online char_id
end
end

def get_player(user_id, options \\ [])
def get_player(user_id, options) do
def get_player(char_id, options \\ [])
def get_player(char_id, options) do
sync = Keyword.get(options, :sync, false)

if sync do
GenServer.call __MODULE__, {:get_player, user_id}
GenServer.call __MODULE__, {:get_player, char_id}
else
do_get_player user_id
do_get_player char_id
end
end

Expand All @@ -38,54 +38,54 @@ defmodule Yggdrasil.Player.Registry do
table_id = :ets.new @registry_ets, [:named_table, :set]
{:ok, %{
:table_id => table_id,
:mon2user => %{ }
:mon2character => %{ }
}}
end

def handle_call({:register, user_id, player_pid}, _from, state) do
case :ets.lookup @registry_ets, user_id do
def handle_call({:register, char_id, player_pid}, _from, state) do
case :ets.lookup @registry_ets, char_id do
[] ->
:ets.insert @registry_ets, {user_id, player_pid}
:ets.insert @registry_ets, {char_id, player_pid}
monitor = Process.monitor player_pid
{:reply, :ok, add_mon2user(state, monitor, user_id)}
{:reply, :ok, add_mon2character(state, monitor, char_id)}
[_] ->
{:reply, {:error, :already_registered}, state}
end
end

def handle_call({:is_online, user_id}, _from, state) do
{:reply, do_is_online(user_id), state}
def handle_call({:is_online, char_id}, _from, state) do
{:reply, do_is_online(char_id), state}
end

def handle_call({:get_player, user_id}, _from, state) do
{:reply, do_get_player(user_id), state}
def handle_call({:get_player, char_id}, _from, state) do
{:reply, do_get_player(char_id), state}
end

def handle_info({:DOWN, monitor, :process, _pid, _reason}, state) do
:ets.delete @registry_ets, state.mon2user[monitor]
{:noreply, remove_mon2user(state, monitor)}
:ets.delete @registry_ets, state.mon2character[monitor]
{:noreply, remove_mon2character(state, monitor)}
end


defp add_mon2user(state, monitor, user_id) do
%{ state | :mon2user => Map.put(state.mon2user, monitor, user_id)}
defp add_mon2character(state, monitor, char_id) do
%{ state | :mon2character => Map.put(state.mon2character, monitor, char_id)}
end

defp remove_mon2user(state, monitor) do
%{ state | :mon2user => Map.delete(state.mon2user, monitor)}
defp remove_mon2character(state, monitor) do
%{ state | :mon2character => Map.delete(state.mon2character, monitor)}
end

defp do_is_online(user_id) do
case do_get_player(user_id) do
defp do_is_online(char_id) do
case do_get_player(char_id) do
nil -> false
_pid -> true
end
end

defp do_get_player(user_id) do
case :ets.lookup @registry_ets, user_id do
defp do_get_player(char_id) do
case :ets.lookup @registry_ets, char_id do
[] -> nil
[{^user_id, player_pid}] -> player_pid
[{^char_id, player_pid}] -> player_pid
end
end
end
4 changes: 2 additions & 2 deletions apps/yggdrasil/lib/yggdrasil/player/supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ defmodule Yggdrasil.Player.Supervisor do
supervise(children, strategy: :simple_one_for_one)
end

def add_player(user_id, args) do
Supervisor.start_child(__MODULE__, [user_id | args])
def add_player(char_id, args) do
Supervisor.start_child(__MODULE__, [char_id | args])
end
end
8 changes: 8 additions & 0 deletions apps/yggdrasil/lib/yggdrasil/resource.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule Yggdrasil.Resource do
use Ecto.Schema

@primary_key {:name, :string, []}
schema "resources" do
timestamps
end
end
10 changes: 10 additions & 0 deletions apps/yggdrasil/lib/yggdrasil/role.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule Yggdrasil.Role do
use Ecto.Schema

schema "roles" do
field :name, :string
has_many :role_permissions, Yggdrasil.RolePermission

timestamps
end
end
13 changes: 13 additions & 0 deletions apps/yggdrasil/lib/yggdrasil/role_permission.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
defmodule Yggdrasil.RolePermission do
use Ecto.Schema

@primary_key false
schema "roles_permissions" do
field :resource, :string
field :permission, :string

belongs_to :role, Yggdrasil.Role

timestamps
end
end
Loading