1- extends RefCounted
1+ @icon ("res://assets/ui/icons/iconoir--network-solid.svg" )
2+ extends Node
23class_name NetworkManager
34
4- ## Manage and interact with the system network settings
5+ ## Manages NetworkManager.
56##
6- ## Allows network management through nmcli
7- ## Reference: https://developer-old.gnome.org/NetworkManager/stable/nmcli.html
7+ ## The [NetworkManager] class is responsible for loading a [NetworkManagerInstance] and
8+ ## calling its 'process()' method each frame.
89
910const bar_0 := preload ("res://assets/ui/icons/wifi-none.svg" )
1011const bar_1 := preload ("res://assets/ui/icons/wifi-low.svg" )
1112const bar_2 := preload ("res://assets/ui/icons/wifi-medium.svg" )
1213const bar_3 := preload ("res://assets/ui/icons/wifi-high.svg" )
14+ const no_network := preload ("res://assets/ui/icons/tabler--network-off.svg" )
15+ const ethernet := preload ("res://assets/ui/icons/mdi--ethernet.svg" )
1316
14- const common_args := ["--terse" , "--color" , "no" ]
15-
16-
17- ## Wireless Access Point
18- class WifiAP :
19- var in_use : bool
20- var bssid : String
21- var ssid : String
22- var mode : String
23- var channel : int
24- var rate : String
25- var strength : int
26- var security : String
27-
28-
29- ## Network device
30- class NetworkDevice :
31- var device : String
32- var type : String
33- var state : String
34- var connection : String
35-
36-
37- ## Returns true if the system has network controls we support
38- static func supports_network () -> bool :
39- var code := OS .execute ("which" , ["nmcli" ])
40- return code == 0
41-
42-
43- ## Returns a list of network devices
44- # $nmcli --terse --color no device
45- # enp5s0:ethernet:connected:Wired connection 1
46- # wlp4s0:wifi:connected:Chonenberg
47- # lo:loopback:connected (externally):lo
48- # p2p-dev-wlp4s0:wifi-p2p:disconnected:
49- static func get_devices () -> Array [NetworkDevice ]:
50- var result : Array [NetworkDevice ] = []
51- var output := _run_nmcli (["device" ])
52- for line in output :
53- var device := NetworkDevice .new ()
54- device .device = line [0 ]
55- device .type = line [1 ]
56- device .state = line [2 ]
57- device .connection = line [3 ]
58- result .append (device )
59-
60- return result
61-
62-
63- ## Returns a list of available wifi access points
64- # $ nmcli --terse --color no dev wifi
65- # :AA\:BB\:CC\:83\:82\:FF:Chronenberg 5GHz:Infra:120:405 Mbit/s:94:▂▄▆█:WPA2
66- # *:AA\:BB\:CC\:83\:82\:FB:Chonenberg:Infra:11:195 Mbit/s:83:▂▄▆█:WPA2
67- static func get_access_points () -> Array [WifiAP ]:
68- var result : Array [WifiAP ] = []
69- var output := _run_nmcli (["dev" , "wifi" ])
70- for line in output :
71- var ap := WifiAP .new ()
72- ap .in_use = line [0 ] == "*"
73- ap .bssid = line [1 ]
74- ap .ssid = line [2 ]
75- ap .mode = line [3 ]
76- ap .channel = line [4 ].to_int ()
77- ap .rate = line [5 ]
78- ap .strength = line [6 ].to_int ()
79- ap .security = line [8 ]
80- result .append (ap )
81-
82- return result
83-
84-
85- ## Returns the currently connected access point
86- static func get_current_access_point () -> WifiAP :
87- var access_points := get_access_points ()
88- for ap in access_points :
89- if ap .in_use :
90- return ap
91- return null
92-
93-
94- ## Connect to the given wifi access point
95- static func connect_access_point (ssid : String , password : String = "" ) -> int :
96- var args := ["dev" , "wifi" , "connect" , ssid ]
97- if password != "" :
98- args .append_array (["password" , password ])
99- var output := []
100- var code := OS .execute ("nmcli" , args , output )
101- if code != OK :
102- push_warning ("Unable to connect to " , ssid , ": " , output [0 ])
103- return code
17+ @export var instance : NetworkManagerInstance = load ("res://core/systems/network/network_manager.tres" ) as NetworkManagerInstance
10418
10519
10620## Returns the texture reflecting the given wifi strength
@@ -114,34 +28,7 @@ static func get_strength_texture(strength: int) -> Texture2D:
11428 return bar_0
11529
11630
117- # Run nmcli with the given arguments. Returns the parsed output.
118- static func _run_nmcli (args : PackedStringArray ) -> Array [PackedStringArray ]:
119- var output := []
120- var cmd_args := common_args .duplicate ()
121- cmd_args .append_array (args )
122- var code := OS .execute ("nmcli" , cmd_args , output )
123- if code != OK :
124- return []
125-
126- return _parse_nmcli (output [0 ])
127-
128-
129- # Parses the terse output of nmcli, which is separated by ':'
130- # $ nmcli --terse --color no dev wifi
131- # :AA\:BB\:CC\:83\:82\:FF:Chronenberg 5GHz:Infra:120:405 Mbit/s:94:▂▄▆█:WPA2
132- # *:AA\:BB\:CC\:83\:82\:FB:Chonenberg:Infra:11:195 Mbit/s:83:▂▄▆█:WPA2
133- static func _parse_nmcli (output : String ) -> Array [PackedStringArray ]:
134- var parsed : Array [PackedStringArray ] = []
135- var lines := output .split ("\n " )
136- for line in lines :
137- var parsed_line := PackedStringArray ()
138- if line == "" :
139- continue
140- line = line .replace ("\\ :" , "%COLON%" )
141- var columns := line .split (":" )
142- for column in columns :
143- column = column .replace ("%COLON%" , ":" )
144- parsed_line .append (column )
145- parsed .append (parsed_line )
146-
147- return parsed
31+ func _process (_delta : float ) -> void :
32+ if not instance :
33+ return
34+ instance .process ()
0 commit comments