termfront 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/CHANGELOG.md +22 -1
- data/README.md +14 -3
- data/lib/termfront/config.rb +1 -0
- data/lib/termfront/network/client.rb +87 -2
- data/lib/termfront/network/connection.rb +47 -3
- data/lib/termfront/network/server.rb +2 -2
- data/lib/termfront/network/wavesfight_client.rb +2 -2
- data/lib/termfront/version.rb +1 -1
- metadata +93 -93
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2fd6067c562cc7a0a01f4c71d3e35582366c77f2e9d677a84fcc6bc30a800748
|
|
4
|
+
data.tar.gz: 0773d031711ed21fcac539ae9b9e90a84c058308ed6d4ea5c7393b4dc85248ff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94d5836a718e20fc6fce13a642f19d30e36294bed15703e265288179a43b0ae3960613cda90cf91f553175a81f2d6b7e2fe4ac2c73b1856f467fc498464e7fea
|
|
7
|
+
data.tar.gz: 2416935f643801b897a5b9080a5bd6570bf9bfe2e13e310ada37696a6f1d1ce2630af6b8397470ac46fc06ffc58baec8aae43e8ac8233d1dc6f89170abbe2e1f
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.0.5
|
data/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,27 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on Keep a Changelog, and this project follows Semantic Versioning as it stabilizes.
|
|
6
6
|
|
|
7
|
-
## [
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.2] - 2026-05-23
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added TLS verification coverage for multiplayer connection settings and certificate trust handling
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Added visible remote shot tracer effects during PvP and Wavesfight multiplayer matches
|
|
18
|
+
- Enabled TLS certificate chain and hostname verification for multiplayer client connections
|
|
19
|
+
- Added support for `TERMFRONT_TLS_CERT_FILE` and `TERMFRONT_TLS_KEY_FILE` when loading the server certificate
|
|
20
|
+
|
|
21
|
+
## [0.1.1] - 2026-05-21
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Changed the default multiplayer server address to `termfront.gamelinks007.net:443`
|
|
26
|
+
|
|
27
|
+
## [0.1.0] - 2026-05-21
|
|
8
28
|
|
|
9
29
|
Initial public gem release candidate.
|
|
10
30
|
|
|
@@ -34,6 +54,7 @@ Initial public gem release candidate.
|
|
|
34
54
|
- Updated PvP match-size selection to support arrow keys in addition to `J`/`K`
|
|
35
55
|
- Disabled quitting PvP matches with `Q` to avoid accidental exits during combat
|
|
36
56
|
- Added Wavesfight arena registration for `Corridor Sweep`, `Stronghold`, and `Final Push`
|
|
57
|
+
- Added SNI hostname support to TLS client connections for `nginx stream`-based 443 routing
|
|
37
58
|
|
|
38
59
|
### Notes
|
|
39
60
|
|
data/README.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
- `paplay`
|
|
23
23
|
- `aplay`
|
|
24
24
|
|
|
25
|
-
RubyGems metadata currently targets Ruby `0.1.
|
|
25
|
+
RubyGems metadata currently targets Ruby `0.1.1`.
|
|
26
26
|
|
|
27
27
|
## Installation
|
|
28
28
|
|
|
@@ -54,6 +54,14 @@ Start a PvP server:
|
|
|
54
54
|
termfront-server
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
Use custom TLS certificate paths:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
TERMFRONT_TLS_CERT_FILE=/path/to/fullchain.pem \
|
|
61
|
+
TERMFRONT_TLS_KEY_FILE=/path/to/privkey.pem \
|
|
62
|
+
termfront-server
|
|
63
|
+
```
|
|
64
|
+
|
|
57
65
|
Use a custom port:
|
|
58
66
|
|
|
59
67
|
```bash
|
|
@@ -62,6 +70,8 @@ termfront-server 9000
|
|
|
62
70
|
|
|
63
71
|
Default PvP port is `7777`.
|
|
64
72
|
|
|
73
|
+
The default multiplayer client address is `termfront.gamelinks007.net:443`.
|
|
74
|
+
|
|
65
75
|
## Controls
|
|
66
76
|
|
|
67
77
|
- `W` `A` `S` `D`: move
|
|
@@ -108,7 +118,8 @@ Wavesfight is a PvE survival mode built on selected campaign maps.
|
|
|
108
118
|
PvP is currently marked experimental.
|
|
109
119
|
|
|
110
120
|
- The server listens on TCP and wraps traffic with TLS.
|
|
111
|
-
- The client connects directly to `host:port
|
|
121
|
+
- The client connects directly to `host:port` and verifies the server certificate and hostname.
|
|
122
|
+
- The default multiplayer endpoint is `termfront.gamelinks007.net:443`.
|
|
112
123
|
- Matchmaking now supports `1v1`, `2v2`, and `4v4`.
|
|
113
124
|
- Players choose the match size on the client, and the server keeps separate queues for each mode.
|
|
114
125
|
- Team matches end when one side is fully eliminated.
|
|
@@ -150,7 +161,7 @@ gem build termfront.gemspec
|
|
|
150
161
|
Install the built gem locally:
|
|
151
162
|
|
|
152
163
|
```bash
|
|
153
|
-
gem install ./termfront-0.1.
|
|
164
|
+
gem install ./termfront-0.1.1.gem
|
|
154
165
|
```
|
|
155
166
|
|
|
156
167
|
## License
|
data/lib/termfront/config.rb
CHANGED
|
@@ -46,7 +46,7 @@ module Termfront
|
|
|
46
46
|
private
|
|
47
47
|
|
|
48
48
|
def prompt_address
|
|
49
|
-
input =
|
|
49
|
+
input = Config::PVP_DEFAULT_ADDRESS
|
|
50
50
|
|
|
51
51
|
STDIN.raw do |stdin|
|
|
52
52
|
loop do
|
|
@@ -80,7 +80,7 @@ module Termfront
|
|
|
80
80
|
data.each_byte do |b|
|
|
81
81
|
case b
|
|
82
82
|
when 27 then return nil
|
|
83
|
-
when 13, 10 then return input.empty? ?
|
|
83
|
+
when 13, 10 then return input.empty? ? Config::PVP_DEFAULT_ADDRESS : input
|
|
84
84
|
when 127, 8 then input = input[0...-1] unless input.empty?
|
|
85
85
|
when 32..126 then input << b.chr
|
|
86
86
|
end
|
|
@@ -336,6 +336,7 @@ module Termfront
|
|
|
336
336
|
remote[:current].health = msg[:h]
|
|
337
337
|
remote[:current].weapon = msg[:w]&.to_sym
|
|
338
338
|
remote[:current].ammo = msg[:am]
|
|
339
|
+
spawn_remote_projectile_effect(msg) if (remote[:current].fire_flash || 0) <= 0 && (msg[:ff] || 0) > 0
|
|
339
340
|
remote[:current].fire_flash = msg[:ff] || 0
|
|
340
341
|
remote[:lerp_t] = 0.0
|
|
341
342
|
end
|
|
@@ -377,6 +378,7 @@ module Termfront
|
|
|
377
378
|
|
|
378
379
|
process_fire_pvp if @player.fire_flash == 4
|
|
379
380
|
@player.fire_flash -= 1 if @player.fire_flash > 0
|
|
381
|
+
update_projectile_effects(dt)
|
|
380
382
|
|
|
381
383
|
@player.update_shield(dt, @stdout, audio: @audio)
|
|
382
384
|
|
|
@@ -476,6 +478,7 @@ module Termfront
|
|
|
476
478
|
render_pvp_hud(buf, cols)
|
|
477
479
|
render_view(buf, view_h, view_w, wtop, wbot, wcol)
|
|
478
480
|
render_remote_players_3d(buf, view_h, view_w, virt_h, dists)
|
|
481
|
+
render_pvp_projectiles(buf, view_h, view_w, virt_h, dists)
|
|
479
482
|
buf << "\e[#{3 + view_h};1H"
|
|
480
483
|
render_pvp_radar(buf, cols, radar_h)
|
|
481
484
|
render_crosshair(buf, view_h, view_w, cols)
|
|
@@ -635,6 +638,64 @@ module Termfront
|
|
|
635
638
|
end
|
|
636
639
|
end
|
|
637
640
|
|
|
641
|
+
def render_pvp_projectiles(buf, view_h, view_w, virt_h, dists)
|
|
642
|
+
dx = Math.cos(@player.angle)
|
|
643
|
+
dy = Math.sin(@player.angle)
|
|
644
|
+
px = -dy * Math.tan(Config::FOV / 2.0)
|
|
645
|
+
py = dx * Math.tan(Config::FOV / 2.0)
|
|
646
|
+
inv = 1.0 / (px * dy - py * dx)
|
|
647
|
+
|
|
648
|
+
sprites = []
|
|
649
|
+
@projectiles.each do |projectile|
|
|
650
|
+
ex = projectile[:x] - @player.x
|
|
651
|
+
ey = projectile[:y] - @player.y
|
|
652
|
+
tx = inv * (dy * ex - dx * ey)
|
|
653
|
+
tz = inv * (-py * ex + px * ey)
|
|
654
|
+
next if tz < 0.2
|
|
655
|
+
|
|
656
|
+
sprites << [tz, tx, projectile]
|
|
657
|
+
end
|
|
658
|
+
sprites.sort_by! { |sprite| -sprite[0] }
|
|
659
|
+
|
|
660
|
+
sprites.each do |tz, tx, projectile|
|
|
661
|
+
sx = ((view_w / 2.0) * (1 + tx / tz)).to_i
|
|
662
|
+
pw = (4.0 / tz).ceil.clamp(1, 5)
|
|
663
|
+
ph = (virt_h / tz * 0.15).ceil.clamp(2, 6)
|
|
664
|
+
vmid = virt_h / 2
|
|
665
|
+
draw_top = [(vmid - ph / 2), 0].max
|
|
666
|
+
draw_bot = [(vmid + ph / 2).clamp(draw_top + 2, virt_h), virt_h].min
|
|
667
|
+
start_x = [sx - pw / 2, 0].max
|
|
668
|
+
end_x = [sx + pw / 2, view_w - 1].min
|
|
669
|
+
|
|
670
|
+
start_x.upto(end_x) do |c|
|
|
671
|
+
next if c < 0 || c >= view_w
|
|
672
|
+
next if dists[c] < tz
|
|
673
|
+
|
|
674
|
+
r_top = (draw_top / 2.0).ceil
|
|
675
|
+
r_bot = [(draw_bot / 2.0).floor, r_top + 1].max
|
|
676
|
+
r_top.upto(r_bot - 1) do |r|
|
|
677
|
+
next if r < 0 || r >= view_h
|
|
678
|
+
|
|
679
|
+
vp0 = r * 2
|
|
680
|
+
vp1 = r * 2 + 1
|
|
681
|
+
top_in = vp0 >= draw_top && vp0 < draw_bot
|
|
682
|
+
bot_in = vp1 >= draw_top && vp1 < draw_bot
|
|
683
|
+
next unless top_in || bot_in
|
|
684
|
+
|
|
685
|
+
proj_color = projectile[:color]
|
|
686
|
+
buf << "\e[#{3 + r};#{c + 1}H"
|
|
687
|
+
buf << if top_in && bot_in
|
|
688
|
+
"\e[38;2;#{proj_color}m\xE2\x96\x88\e[0m"
|
|
689
|
+
elsif top_in
|
|
690
|
+
"\e[38;2;#{proj_color}m\xE2\x96\x80\e[0m"
|
|
691
|
+
else
|
|
692
|
+
"\e[38;2;#{proj_color}m\xE2\x96\x84\e[0m"
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
end
|
|
696
|
+
end
|
|
697
|
+
end
|
|
698
|
+
|
|
638
699
|
def tint_player_color(color, mode)
|
|
639
700
|
return nil unless color
|
|
640
701
|
return color if mode == :ally
|
|
@@ -822,6 +883,30 @@ module Termfront
|
|
|
822
883
|
STDIN.raw { |s| s.getc }
|
|
823
884
|
end
|
|
824
885
|
|
|
886
|
+
def spawn_remote_projectile_effect(msg)
|
|
887
|
+
shock = msg[:w].to_s.start_with?("shock")
|
|
888
|
+
color = shock ? "80;220;255" : "255;210;80"
|
|
889
|
+
speed = shock ? 18.0 : 14.0
|
|
890
|
+
angle = msg[:a]
|
|
891
|
+
@projectiles << {
|
|
892
|
+
x: msg[:x],
|
|
893
|
+
y: msg[:y],
|
|
894
|
+
vx: Math.cos(angle) * speed,
|
|
895
|
+
vy: Math.sin(angle) * speed,
|
|
896
|
+
ttl: 0.18,
|
|
897
|
+
color: color
|
|
898
|
+
}
|
|
899
|
+
end
|
|
900
|
+
|
|
901
|
+
def update_projectile_effects(dt)
|
|
902
|
+
@projectiles.reject! do |projectile|
|
|
903
|
+
projectile[:x] += projectile[:vx] * dt
|
|
904
|
+
projectile[:y] += projectile[:vy] * dt
|
|
905
|
+
projectile[:ttl] -= dt
|
|
906
|
+
projectile[:ttl] <= 0 || @map.wall_at?(projectile[:x], projectile[:y])
|
|
907
|
+
end
|
|
908
|
+
end
|
|
909
|
+
|
|
825
910
|
def notify_death_if_needed
|
|
826
911
|
return unless @player.dead
|
|
827
912
|
return if @sent_dead
|
|
@@ -3,29 +3,47 @@
|
|
|
3
3
|
require "socket"
|
|
4
4
|
require "openssl"
|
|
5
5
|
require "json"
|
|
6
|
+
require "time"
|
|
6
7
|
|
|
7
8
|
module Termfront
|
|
8
9
|
module Network
|
|
9
10
|
class Connection
|
|
11
|
+
PeerInfo = Struct.new(
|
|
12
|
+
:certificate_sha256,
|
|
13
|
+
:public_key_sha256,
|
|
14
|
+
:subject,
|
|
15
|
+
:issuer,
|
|
16
|
+
:not_after,
|
|
17
|
+
keyword_init: true
|
|
18
|
+
)
|
|
19
|
+
|
|
10
20
|
attr_reader :rtt
|
|
21
|
+
attr_reader :peer_info
|
|
11
22
|
|
|
12
23
|
def initialize
|
|
13
24
|
@sock = nil
|
|
14
25
|
@buf = +""
|
|
15
26
|
@ping_ts = 0
|
|
16
27
|
@rtt = 0
|
|
28
|
+
@peer_info = nil
|
|
17
29
|
end
|
|
18
30
|
|
|
19
|
-
def connect(host, port)
|
|
31
|
+
def connect(host, port, ca_file: nil)
|
|
20
32
|
tcp = TCPSocket.new(host, port)
|
|
21
33
|
tcp.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
22
34
|
|
|
23
|
-
ctx =
|
|
24
|
-
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
35
|
+
ctx = build_ssl_context(ca_file: ca_file)
|
|
25
36
|
@sock = OpenSSL::SSL::SSLSocket.new(tcp, ctx)
|
|
26
37
|
@sock.hostname = host if @sock.respond_to?(:hostname=)
|
|
27
38
|
@sock.sync = true
|
|
28
39
|
@sock.connect
|
|
40
|
+
@sock.post_connection_check(host)
|
|
41
|
+
@peer_info = build_peer_info(@sock.peer_cert)
|
|
42
|
+
rescue StandardError
|
|
43
|
+
tcp&.close
|
|
44
|
+
@sock = nil
|
|
45
|
+
@peer_info = nil
|
|
46
|
+
raise
|
|
29
47
|
end
|
|
30
48
|
|
|
31
49
|
def send_msg(hash)
|
|
@@ -76,6 +94,7 @@ module Termfront
|
|
|
76
94
|
nil
|
|
77
95
|
end
|
|
78
96
|
@sock = nil
|
|
97
|
+
@peer_info = nil
|
|
79
98
|
end
|
|
80
99
|
|
|
81
100
|
def connected?
|
|
@@ -96,6 +115,31 @@ module Termfront
|
|
|
96
115
|
def clock
|
|
97
116
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
98
117
|
end
|
|
118
|
+
|
|
119
|
+
def build_ssl_context(ca_file:)
|
|
120
|
+
ctx = OpenSSL::SSL::SSLContext.new
|
|
121
|
+
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
122
|
+
ctx.verify_hostname = true if ctx.respond_to?(:verify_hostname=)
|
|
123
|
+
ctx.cert_store = build_cert_store(ca_file: ca_file)
|
|
124
|
+
ctx
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def build_cert_store(ca_file:)
|
|
128
|
+
store = OpenSSL::X509::Store.new
|
|
129
|
+
store.set_default_paths
|
|
130
|
+
store.add_file(ca_file) if ca_file
|
|
131
|
+
store
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def build_peer_info(cert)
|
|
135
|
+
PeerInfo.new(
|
|
136
|
+
certificate_sha256: OpenSSL::Digest::SHA256.hexdigest(cert.to_der),
|
|
137
|
+
public_key_sha256: OpenSSL::Digest::SHA256.hexdigest(cert.public_key.to_der),
|
|
138
|
+
subject: cert.subject.to_s,
|
|
139
|
+
issuer: cert.issuer.to_s,
|
|
140
|
+
not_after: cert.not_after.utc
|
|
141
|
+
)
|
|
142
|
+
end
|
|
99
143
|
end
|
|
100
144
|
end
|
|
101
145
|
end
|
|
@@ -589,8 +589,8 @@ module Termfront
|
|
|
589
589
|
end
|
|
590
590
|
|
|
591
591
|
def load_or_create_cert
|
|
592
|
-
cert_file = "termfront_server.crt"
|
|
593
|
-
key_file = "termfront_server.key"
|
|
592
|
+
cert_file = ENV.fetch("TERMFRONT_TLS_CERT_FILE", "termfront_server.crt")
|
|
593
|
+
key_file = ENV.fetch("TERMFRONT_TLS_KEY_FILE", "termfront_server.key")
|
|
594
594
|
|
|
595
595
|
if File.exist?(cert_file) && File.exist?(key_file)
|
|
596
596
|
cert = OpenSSL::X509::Certificate.new(File.read(cert_file))
|
|
@@ -43,7 +43,7 @@ module Termfront
|
|
|
43
43
|
private
|
|
44
44
|
|
|
45
45
|
def prompt_address
|
|
46
|
-
input =
|
|
46
|
+
input = Config::PVP_DEFAULT_ADDRESS
|
|
47
47
|
|
|
48
48
|
STDIN.raw do |stdin|
|
|
49
49
|
loop do
|
|
@@ -76,7 +76,7 @@ module Termfront
|
|
|
76
76
|
data.each_byte do |b|
|
|
77
77
|
case b
|
|
78
78
|
when 27 then return nil
|
|
79
|
-
when 13, 10 then return input.empty? ?
|
|
79
|
+
when 13, 10 then return input.empty? ? Config::PVP_DEFAULT_ADDRESS : input
|
|
80
80
|
when 127, 8 then input = input[0...-1] unless input.empty?
|
|
81
81
|
when 32..126 then input << b.chr
|
|
82
82
|
end
|
data/lib/termfront/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,119 +1,119 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: termfront
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
|
|
7
|
+
- S-H-GAMELINKS
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
|
-
description:
|
|
12
|
+
description: A terminal-based first-person shooter with DDA raycasting, campaign mode,
|
|
13
|
+
and PvP multiplayer.
|
|
13
14
|
email:
|
|
14
|
-
|
|
15
|
+
- gamelinks007@gmail.com
|
|
15
16
|
executables:
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
- termfront
|
|
18
|
+
- termfront-server
|
|
18
19
|
extensions: []
|
|
19
20
|
extra_rdoc_files: []
|
|
20
21
|
files:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
22
|
+
- ".ruby-version"
|
|
23
|
+
- CHANGELOG.md
|
|
24
|
+
- LICENSE
|
|
25
|
+
- LICENSE.txt
|
|
26
|
+
- README.md
|
|
27
|
+
- Rakefile
|
|
28
|
+
- data/audio/THIRD_PARTY_NOTICES.md
|
|
29
|
+
- data/audio/beep_02.ogg
|
|
30
|
+
- data/audio/button1.ogg
|
|
31
|
+
- data/audio/complete.ogg
|
|
32
|
+
- data/audio/manifest.json
|
|
33
|
+
- data/audio/mission_bgm.wav
|
|
34
|
+
- data/audio/mission_clear_se.wav
|
|
35
|
+
- data/audio/on.ogg
|
|
36
|
+
- data/audio/page_se.wav
|
|
37
|
+
- data/audio/sector.mp3
|
|
38
|
+
- data/audio/sfx_22b.ogg
|
|
39
|
+
- data/audio/shield_alarm_se.wav
|
|
40
|
+
- data/audio/shield_regen_se.wav
|
|
41
|
+
- data/audio/shoot_01.ogg
|
|
42
|
+
- data/audio/terminal_se.wav
|
|
43
|
+
- data/audio/title.mp3
|
|
44
|
+
- data/audio/title_bgm.wav
|
|
45
|
+
- data/audio/victory.mp3
|
|
46
|
+
- data/events/corridor_sweep.json
|
|
47
|
+
- data/events/final_push.json
|
|
48
|
+
- data/events/stronghold.json
|
|
49
|
+
- data/events/the_gauntlet.json
|
|
50
|
+
- data/events/training_grounds.json
|
|
51
|
+
- exe/termfront
|
|
52
|
+
- exe/termfront-server
|
|
53
|
+
- lib/termfront.rb
|
|
54
|
+
- lib/termfront/audio_manager.rb
|
|
55
|
+
- lib/termfront/config.rb
|
|
56
|
+
- lib/termfront/demo_player.rb
|
|
57
|
+
- lib/termfront/drop_item/base.rb
|
|
58
|
+
- lib/termfront/drop_item/weapon.rb
|
|
59
|
+
- lib/termfront/enemy/base.rb
|
|
60
|
+
- lib/termfront/enemy/crawler.rb
|
|
61
|
+
- lib/termfront/enemy/executor.rb
|
|
62
|
+
- lib/termfront/game.rb
|
|
63
|
+
- lib/termfront/input.rb
|
|
64
|
+
- lib/termfront/map.rb
|
|
65
|
+
- lib/termfront/mission/base.rb
|
|
66
|
+
- lib/termfront/mission/corridor_sweep.rb
|
|
67
|
+
- lib/termfront/mission/event_loader.rb
|
|
68
|
+
- lib/termfront/mission/event_runtime.rb
|
|
69
|
+
- lib/termfront/mission/final_push.rb
|
|
70
|
+
- lib/termfront/mission/stronghold.rb
|
|
71
|
+
- lib/termfront/mission/the_gauntlet.rb
|
|
72
|
+
- lib/termfront/mission/training.rb
|
|
73
|
+
- lib/termfront/mission/training_grounds.rb
|
|
74
|
+
- lib/termfront/network/client.rb
|
|
75
|
+
- lib/termfront/network/connection.rb
|
|
76
|
+
- lib/termfront/network/server.rb
|
|
77
|
+
- lib/termfront/network/wavesfight_client.rb
|
|
78
|
+
- lib/termfront/opponent.rb
|
|
79
|
+
- lib/termfront/player.rb
|
|
80
|
+
- lib/termfront/projectile.rb
|
|
81
|
+
- lib/termfront/remote_enemy.rb
|
|
82
|
+
- lib/termfront/renderer.rb
|
|
83
|
+
- lib/termfront/scene_player.rb
|
|
84
|
+
- lib/termfront/sprite.rb
|
|
85
|
+
- lib/termfront/terminal_output.rb
|
|
86
|
+
- lib/termfront/title_screen.rb
|
|
87
|
+
- lib/termfront/version.rb
|
|
88
|
+
- lib/termfront/weapon/assault_rifle.rb
|
|
89
|
+
- lib/termfront/weapon/base.rb
|
|
90
|
+
- lib/termfront/weapon/pistol.rb
|
|
91
|
+
- lib/termfront/weapon/shock_pistol.rb
|
|
92
|
+
- lib/termfront/weapon/shock_rifle.rb
|
|
93
|
+
- sig/termfront.rbs
|
|
94
|
+
homepage: https://github.com/S-H-GAMELINKS/termfront
|
|
93
95
|
licenses:
|
|
94
|
-
|
|
96
|
+
- MIT
|
|
95
97
|
metadata:
|
|
96
|
-
allowed_push_host:
|
|
97
|
-
homepage_uri:
|
|
98
|
-
source_code_uri:
|
|
99
|
-
changelog_uri:
|
|
98
|
+
allowed_push_host: https://rubygems.org
|
|
99
|
+
homepage_uri: https://github.com/S-H-GAMELINKS/termfront
|
|
100
|
+
source_code_uri: https://github.com/S-H-GAMELINKS/termfront
|
|
101
|
+
changelog_uri: https://github.com/S-H-GAMELINKS/termfront/blob/main/CHANGELOG.md
|
|
100
102
|
rdoc_options: []
|
|
101
103
|
require_paths:
|
|
102
|
-
|
|
104
|
+
- lib
|
|
103
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
106
|
requirements:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
version: 3.2.0
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: 3.2.0
|
|
109
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
111
|
requirements:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
version: "0"
|
|
112
|
+
- - ">="
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: '0'
|
|
115
115
|
requirements: []
|
|
116
|
-
rubygems_version: 4.
|
|
116
|
+
rubygems_version: 4.0.10
|
|
117
117
|
specification_version: 4
|
|
118
118
|
summary: Terminal FPS game with raycasting engine
|
|
119
119
|
test_files: []
|