Class: Sc2::Ports

Inherits:
Object
  • Object
show all
Defined in:
lib/sc2ai/ports.rb

Overview

Produces suitable PortConfig based on start_port and num_players.

Community-consensus on port usage: where start_port is x
term "start_port" only used for calculation: x
legacy, ignored port: x+1
@server.game_port: x+2, @server.base_port: x+3
below is meant to be repeated, but client only allows 1 additional client. player 2:
@client_ports.game_port: x+4, @client_ports.base_port: x+5

Class Method Summary collapse

Class Method Details

.port_available?(port) ⇒ Boolean

Checks if port is open

Parameters:

  • port (String, Integer)

    check if open

Returns:

  • (Boolean)


76
77
78
# File 'lib/sc2ai/ports.rb', line 76

def port_available?(port)
  !!bind(port)
end

.port_config_auto(num_players:) ⇒ PortConfig

Checks system for open ports to get a list of ports for num_players since start_port is purely cosmetic, it’s set to the first port, minus two

Parameters:

  • num_players (Integer)

    Player count which require clients

Returns:



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
# File 'lib/sc2ai/ports.rb', line 37

def port_config_auto(num_players:)
  return @auto_port_config unless @auto_port_config.nil?

  if num_players <= 1
    @auto_port_config = PortConfig.new(start_port: 0,
      num_players:,
      ports: [])
    return @auto_port_config
  end

  max_retry = 10
  try = 0

  # First, attempt to grab a random open port and test sequentially ahead
  while try < max_retry
    try += 1

    random_port = random_available_port
    next unless random_port

    random_port_range = port_range(random_port, num_players)
    # Ensure all are available
    next unless random_port_range.detect { |p| !port_available?(p) }.nil?

    start_port = random_port_range.first - 2
    # If so, store and return a port config
    @auto_port_config = PortConfig.new(start_port:,
      num_players:,
      ports: random_port_range.to_a)

    # And memorise our random ports used, for good measure
    @used_random_ports << random_port_range.to_a
    @used_random_ports.uniq!
    return @auto_port_config
  end
end

.port_config_basic(start_port:, num_players:) ⇒ PortConfig

Basic port config using the magic of incrementation on start_port

Parameters:

  • start_port (Integer)
  • num_players (Integer)

    Player count which require clients

Returns:



27
28
29
30
31
# File 'lib/sc2ai/ports.rb', line 27

def port_config_basic(start_port:, num_players:)
  PortConfig.new(start_port:,
    num_players:,
    ports: port_range(start_port.to_i + 2, num_players).to_a)
end

.random_available_portInteger

Checks system for a random available port which we haven’t used yet

Returns:

  • (Integer)

    port

Raises:



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/sc2ai/ports.rb', line 83

def random_available_port
  10.times do
    port = bind(0)
    unless @used_random_ports.include?(port)
      @used_random_ports << port
      return port
    end
  end

  # Alternatively, grab some random ports and check if they are open
  # Try random ports as a last resort.
  10.times do
    port = rand(15_000..25_000)
    if port_available?(port) && !@used_random_ports.include?(port)
      @used_random_ports << port
      return port
    end
  end

  raise Error, "no free ports found"
end