From 97d5bd9ace8070bb8203882343abd52052999800 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Tue, 11 Mar 2025 09:52:32 -0700 Subject: [PATCH] loot --- .gitignore | 1 + .idea/gambosite.iml | 90 ++++++++++++----------- app/controllers/admin_controller.rb | 5 +- app/controllers/bot_controller.rb | 17 +++-- app/controllers/loot_controller.rb | 43 +++++++++++ app/helpers/loot_helper.rb | 2 + app/models/loot.rb | 34 +++++++++ app/models/player.rb | 28 +++++++ app/views/admin/index.html.erb | 14 +++- app/views/loot/index.html.erb | 27 +++++++ app/views/loot/list.html.erb | 25 +++++++ config/routes.rb | 13 +++- db/migrate/20250310212905_create_loots.rb | 13 ++++ db/schema.rb | 15 +++- db/seeds.rb | 1 + test/controllers/loot_controller_test.rb | 7 ++ test/fixtures/loots.yml | 13 ++++ test/models/loot_test.rb | 7 ++ 18 files changed, 294 insertions(+), 61 deletions(-) create mode 100644 app/controllers/loot_controller.rb create mode 100644 app/helpers/loot_helper.rb create mode 100644 app/models/loot.rb create mode 100644 app/views/loot/index.html.erb create mode 100644 app/views/loot/list.html.erb create mode 100644 db/migrate/20250310212905_create_loots.rb create mode 100644 db/seeds.rb create mode 100644 test/controllers/loot_controller_test.rb create mode 100644 test/fixtures/loots.yml create mode 100644 test/models/loot_test.rb diff --git a/.gitignore b/.gitignore index 63c4bf6..2be09c1 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ *.sqlite3* *DS_store* +config/secrets.yml \ No newline at end of file diff --git a/.idea/gambosite.iml b/.idea/gambosite.iml index c47f4f1..f698c78 100644 --- a/.idea/gambosite.iml +++ b/.idea/gambosite.iml @@ -153,76 +153,78 @@ diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 8bc4b91..f9f4d51 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -1,7 +1,4 @@ class AdminController < ApplicationController - # echo "ya got butts?" | sha256 - PASSWORD = "50cf9308a2cd117a16f7c1f8eb2267fb87556066403b751f8fbf0af159bc9bac" - before_action :authenticate_admin, only: [:index, :set_alt, :clear_alt ] def index @@ -42,7 +39,7 @@ class AdminController < ApplicationController def login_submit pw = params[:password] - if pw == PASSWORD + if pw == ENV["ADMINPW"] session[:user_id] = 1 redirect_to admin_path, notice: "Logged in!" else diff --git a/app/controllers/bot_controller.rb b/app/controllers/bot_controller.rb index 58093b4..be5c04a 100644 --- a/app/controllers/bot_controller.rb +++ b/app/controllers/bot_controller.rb @@ -2,15 +2,16 @@ class BotController < ApplicationController skip_before_action :verify_authenticity_token before_action :authenticate - def players - + def leaderboard + players = Player.where(main_player_id: nil).order(purse: :desc) + render json: players end - def summary - - end - - def player_name - + def lords + players = Player.where(main_player_id: nil).order(purse: :desc) + lords = [] + lords << players.first + lords << players.last + render json: lords end end diff --git a/app/controllers/loot_controller.rb b/app/controllers/loot_controller.rb new file mode 100644 index 0000000..5941a38 --- /dev/null +++ b/app/controllers/loot_controller.rb @@ -0,0 +1,43 @@ +class LootController < ApplicationController + skip_before_action :verify_authenticity_token, only: [ :create ] + before_action :authenticate, only: [ :create ] + + respond_to? :json + + def create + @loot = Loot.new(item_id: params[:item_id], item_name: params[:item_name], timestamp: params[:timestamp], roll_type: params[:roll_type]) + + player = Player.find_by(name: params[:player]) + if player.nil? + player = Player.new(name: params[:player], wins: 0, losses: 0, purse: 0) + player.save + end + @loot.player = player + + if @loot.save + render json: {}, status: :ok + else + render json: { error: "Unable to process input" }, status: :unprocessable_content + end + end + + def index + @players = Player.all.reject(&:alt?).map { |player| [ + player.name, + player.get_loot_count_with_roll("mainspec"), + player.get_loot_count_with_roll("minor"), + player.get_loot_count_with_roll("offspec"), + player.get_loot_count_with_roll("transmog"), + ]}.sort + end + + def list + @loot = Loot.all.sort_by &:timestamp + end + + private + + def already_reported_response + render json: { error: "Already reported this loot" }, status: :already_reported + end +end diff --git a/app/helpers/loot_helper.rb b/app/helpers/loot_helper.rb new file mode 100644 index 0000000..17959b8 --- /dev/null +++ b/app/helpers/loot_helper.rb @@ -0,0 +1,2 @@ +module LootHelper +end diff --git a/app/models/loot.rb b/app/models/loot.rb new file mode 100644 index 0000000..8d79de2 --- /dev/null +++ b/app/models/loot.rb @@ -0,0 +1,34 @@ +class Loot < ApplicationRecord + belongs_to :player + + def player_name_with_alt + if self.player.alt? + "#{self.player.name} (alt of #{self.player.main_player.name})" + else + self.player.name + end + end + + def wowhead + "https://wowhead.com/item=#{self.item_id}" + end + + def roll_type_pretty + case self.roll_type + when "mainspec" + "Main Spec" + when "offspec" + "Offspec" + when "minor" + "Minor Upgrade" + when "transmog" + "Transmog" + else + "Unknown" + end + end + + def date + self.timestamp&.strftime("%m/%d/%Y") + end +end \ No newline at end of file diff --git a/app/models/player.rb b/app/models/player.rb index f6b20db..57aaab6 100644 --- a/app/models/player.rb +++ b/app/models/player.rb @@ -5,6 +5,9 @@ class Player < ApplicationRecord # A Player can have multiple alts has_many :alternate_players, class_name: "Player", foreign_key: "main_player_id" + # A Player can have many loots + has_many :loots + validate :no_circular_references def total_wins @@ -35,6 +38,10 @@ class Player < ApplicationRecord self.main_player end + def has_alts? + self.alternate_players.count > 0 + end + def main_name if alt? self.main_player.name @@ -46,4 +53,25 @@ class Player < ApplicationRecord errors.add(:main_account, "circular reference") end end + + def get_loot + loot = Loot.where(player_id: self.id) + self.alternate_players.each do |alt| + loot << Loot.where(player_id: alt.id) + end + loot + end + + def get_loot_with_roll(roll) + ids = [self.id] + self.alternate_players.pluck(:id) + Loot.where(player_id: ids, roll_type: roll) + end + + def get_loot_count + get_loot.size + end + + def get_loot_count_with_roll(roll) + get_loot_with_roll(roll).size + end end diff --git a/app/views/admin/index.html.erb b/app/views/admin/index.html.erb index 2752f22..853df29 100644 --- a/app/views/admin/index.html.erb +++ b/app/views/admin/index.html.erb @@ -40,6 +40,18 @@ <%= submit_tag "Set Alt", id: "set-alt-button" %> <% end %> + + <% form_with(url: "/admin/set_lootban", method: :post, local: true) do %> +

Set Lootban

+ + + <%= submit_tag "Set Lootban", id: "set-lootban-button" %> + <% end %> + + <% form_with(url: "/admin/delete_lootban", method: :post, local: true) do %> + <%= submit_tag "Clear Lootban", id: "clear-lootban-button" %> + <% end %> + Leaderboard - Logout + diff --git a/app/views/loot/index.html.erb b/app/views/loot/index.html.erb new file mode 100644 index 0000000..ca27a25 --- /dev/null +++ b/app/views/loot/index.html.erb @@ -0,0 +1,27 @@ +

Seasonal Loot Distribution

+ +<% if @players.any? %> +
+
+
+
Player
+
Main Spec
+
Minor Upgrade
+
Offspec
+
Transmog
+
+ <% @players.each do |player| %> +
+
<%= player[0] %>
+
<%= player[1]%>
+
<%= player[2]%>
+
<%= player[3] %>
+
<%= player[4] %>
+
+ <% end %> +
+ Loot List +
+<% else %> +

No loot records exist

+<% end %> diff --git a/app/views/loot/list.html.erb b/app/views/loot/list.html.erb new file mode 100644 index 0000000..c4a086e --- /dev/null +++ b/app/views/loot/list.html.erb @@ -0,0 +1,25 @@ +

Seasonal Loot List

+ +<% if @loot.any? %> +
+
+
+
Date
+
Player
+
Item
+
Roll Type
+
+ <% @loot.each do |l| %> +
+
<%= l.date %>
+
<%= l.player_name_with_alt %>
+
<%= link_to l.item_name, l.wowhead, target: "_blank", rel: "nofollow" %>
+
<%= l.roll_type_pretty %>
+
+ <% end %> +
+ Loot Distribution +
+<% else %> +

No loot records exist

+<% end %> diff --git a/config/routes.rb b/config/routes.rb index bea0bd0..7facfa7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -24,9 +24,9 @@ Rails.application.routes.draw do match "discord" => redirect("https://discord.gg/hQShdPMy7p"), via: [ :get ] # Bot - get "bot/players" => "bot#players" - get "bot/player/:id" => "bot#player_name" - get "bot/summary" => "bot#summary" + get "bot/leaderboard" => "bot#leaderboard" + get "bot/lords" => "bot#lords" + get "bot/weekly" => "bot#weekly" # Admin get "admin", to: "admin#index" @@ -35,4 +35,11 @@ Rails.application.routes.draw do get "admin/login", to: "admin#login" post "admin/login_submit", to: "admin#login_submit" get "admin/destroy", to: "admin#destroy" + post "admin/set_lootban", to: "admin#set_lootban" + post "admin/delete_lootban", to: "admin#clear_lootban" + + # Loot + resources :loot, only: [ :create ], defaults: { format: :json } + get "loot", to: "loot#index" + get "loot/list", to: "loot#list" end diff --git a/db/migrate/20250310212905_create_loots.rb b/db/migrate/20250310212905_create_loots.rb new file mode 100644 index 0000000..365d387 --- /dev/null +++ b/db/migrate/20250310212905_create_loots.rb @@ -0,0 +1,13 @@ +class CreateLoots < ActiveRecord::Migration[8.0] + def change + create_table :loots do |t| + t.integer :item_id + t.datetime :timestamp + t.string :item_name + t.string :roll_type + t.references :player, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 57eb92e..cd9873a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_02_27_233421) do +ActiveRecord::Schema[8.0].define(version: 2025_03_10_212905) do create_table "api_keys", force: :cascade do |t| t.string "key" t.string "client" @@ -38,6 +38,17 @@ ActiveRecord::Schema[8.0].define(version: 2025_02_27_233421) do t.datetime "updated_at", null: false end + create_table "loots", force: :cascade do |t| + t.integer "item_id" + t.datetime "timestamp" + t.string "item_name" + t.string "roll_type" + t.integer "player_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["player_id"], name: "index_loots_on_player_id" + end + create_table "players", force: :cascade do |t| t.string "name" t.integer "wins" @@ -48,4 +59,6 @@ ActiveRecord::Schema[8.0].define(version: 2025_02_27_233421) do t.integer "main_player_id" t.index ["main_player_id"], name: "index_players_on_main_player_id" end + + add_foreign_key "loots", "players" end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..f0d853d --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1 @@ +ApiKey.create(client: "test", key: "12345") diff --git a/test/controllers/loot_controller_test.rb b/test/controllers/loot_controller_test.rb new file mode 100644 index 0000000..376e163 --- /dev/null +++ b/test/controllers/loot_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class LootControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/loots.yml b/test/fixtures/loots.yml new file mode 100644 index 0000000..839928f --- /dev/null +++ b/test/fixtures/loots.yml @@ -0,0 +1,13 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + itemid: 1 + timestamp: 2025-03-10 14:29:05 + itemname: MyString + player: one + +two: + itemid: 1 + timestamp: 2025-03-10 14:29:05 + itemname: MyString + player: two diff --git a/test/models/loot_test.rb b/test/models/loot_test.rb new file mode 100644 index 0000000..100e7d3 --- /dev/null +++ b/test/models/loot_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class LootTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end