Skip to content

Commit

Permalink
ETF2L and RGL API integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Arie committed Aug 13, 2024
1 parent 8f53356 commit 7c27890
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 0 deletions.
48 changes: 48 additions & 0 deletions app/models/etf2l_profile.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

class Etf2lProfile
attr_accessor :json

def initialize(profile_body)
@json = JSON.parse(profile_body)
end

def name
json.dig('player', 'name')
end

def banned?
active_bans.any?
end

def ban_reason
return nil if active_bans.none?

active_bans.map { |b| b['reason'] }.join(', ')
end

def ban_expires_at
return nil if active_bans.none?

active_bans.map { |b| Time.at(b['end']).to_date }.join(', ')
end

def self.fetch(steam_uid)
response_body = Etf2lApi.profile(steam_uid)
new(response_body) if response_body
end

private

def active_bans
@active_bans ||= begin
now = Time.now.to_i
bans = json.dig('player', 'bans')
if bans&.any?
bans.reject { |b| now > b['end'].to_i }
else
[]
end
end
end
end
16 changes: 16 additions & 0 deletions app/models/league_ban.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class LeagueBan
def self.fetch(steam_uid)
klass = if SITE_HOST == 'serveme.tf'
Etf2lProfile
elsif SITE_HOST == 'na.serveme.tf'
RglProfile
end

return unless klass

profile = klass.fetch(steam_uid)
profile.banned? && profile
end
end
4 changes: 4 additions & 0 deletions app/models/reservation_player.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ def self.banned_ip?(ip)
banned_ranges.any? { |range| range.include?(ip) }
end

def self.banned_league_uid?(steam_id64)
LeagueBan.fetch(steam_id64)&.banned?
end

def self.banned_uids
@banned_uids ||= CSV.read(Rails.root.join('doc', 'banned_steam_ids.csv'), headers: true).to_h { |row| [row['steam_id64'].to_i, row['reason']] }
end
Expand Down
32 changes: 32 additions & 0 deletions app/models/rgl_profile.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

class RglProfile
attr_accessor :json

def initialize(profile_body)
@json = JSON.parse(profile_body)
end

def name
json['name']
end

def banned?
json.dig('status', 'isBanned') == true
end

def ban_reason
reason = json.dig('banInformation', 'reason')
ActionView::Base.full_sanitizer.sanitize(reason) if reason
end

def ban_expires_at
expires_at = json.dig('banInformation', 'endsAt')
expires_at && Date.parse(expires_at)
end

def self.fetch(steam_uid)
response_body = RglApi.profile(steam_uid)
new(response_body) if response_body
end
end
24 changes: 24 additions & 0 deletions app/services/etf2l_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

class Etf2lApi
def self.profile(steam_uid)
cached_profile_response(steam_uid) || fetch_profile(steam_uid)
end

def self.cached_profile_response(steam_uid)
Rails.cache.read("etf2l_profile_#{steam_uid}")
end

def self.fetch_profile(steam_uid)
response = etf2l_connection.get("player/#{steam_uid}")
return unless response.success?

Rails.cache.write("etf2l_profile_#{steam_uid}", response.body, expires_in: 1.day)

response.body
end

def self.etf2l_connection
Faraday.new(url: 'https://api-v2.etf2l.org/')
end
end
24 changes: 24 additions & 0 deletions app/services/rgl_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

class RglApi
def self.profile(steam_uid)
cached_profile_response(steam_uid) || fetch_profile(steam_uid)
end

def self.cached_profile_response(steam_uid)
Rails.cache.read("rgl_profile_#{steam_uid}")
end

def self.fetch_profile(steam_uid)
response = rgl_connection.get("v0/profile/#{steam_uid}")
return unless response.success? || response.status == 404

Rails.cache.write("rgl_profile_#{steam_uid}", response.body, expires_in: 1.day)

response.body
end

def self.rgl_connection
Faraday.new(url: 'https://api.rgl.gg/')
end
end
2 changes: 2 additions & 0 deletions app/workers/log_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ def handle_connect
elsif (ReservationPlayer.banned_uid?(community_id) || ReservationPlayer.banned_ip?(ip)) && !ReservationPlayer.whitelisted_uid?(community_id)
reservation.server.rcon_exec "banid 0 #{event.player.steam_id} kick; addip 0 #{ip}"
Rails.logger.info "Removed banned player with UID #{community_id}, IP #{event.message}, name #{event.player.name}, from reservation #{reservation_id}"
elsif (banned_league_profile = LeagueBan.fetch(community_id))
Rails.logger.info "League banned player with UID #{community_id}, IP #{event.message}, name #{event.player.name} connected to reservation #{reservation_id}: #{banned_league_profile.ban_reason}"
elsif reservation.server.supports_mitigations?
AllowReservationPlayerWorker.perform_async(rp.id)
end
Expand Down

0 comments on commit 7c27890

Please sign in to comment.