@@ -55,6 +55,21 @@ std::vector<std::string> g_app_logs;
5555void add_app_log (const std::string& msg) {
5656 if (g_app_logs.size () > 15 ) g_app_logs.erase (g_app_logs.begin ());
5757 g_app_logs.push_back (msg);
58+
59+ if (g_dev_mode) {
60+ int sock = socket (AF_INET, SOCK_DGRAM, 0 );
61+ if (sock >= 0 ) {
62+ int opt = 1 ;
63+ setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof (opt));
64+ struct sockaddr_in addr;
65+ memset (&addr, 0 , sizeof (addr));
66+ addr.sin_family = AF_INET;
67+ addr.sin_port = htons (2828 );
68+ addr.sin_addr .s_addr = INADDR_BROADCAST;
69+ sendto (sock, msg.c_str (), msg.length (), 0 , (struct sockaddr *)&addr, sizeof (addr));
70+ close (sock);
71+ }
72+ }
5873}
5974
6075std::string get_latest_version (std::string& date) {
@@ -83,6 +98,10 @@ std::string get_latest_version(std::string& date) {
8398 if (!date.empty () && date.length () > 10 ) date = date.substr (0 , 10 );
8499 if (!version.empty () && version[0 ] == ' v' ) version = version.substr (1 );
85100 } else {
101+ std::string errMsg = j.value (" message" , " API Limit or Missing Release" );
102+ char errLog[256 ];
103+ snprintf (errLog, sizeof (errLog), " \x1b [31m[ERROR] Update check: %s\x1b [0m" , errMsg.substr (0 , 50 ).c_str ());
104+ add_app_log (errLog);
86105 version = " none" ;
87106 }
88107 } else {
@@ -154,7 +173,7 @@ std::string get_sysmodule_ip() {
154173 u32 cur_ip = 0 ;
155174 if (R_SUCCEEDED (nifmGetCurrentIpAddress (&cur_ip)) && cur_ip != 0 ) {
156175 struct in_addr addr; addr.s_addr = cur_ip;
157- if ( strcmp ( inet_ntoa (addr), " 192.168.1.35 " ) == 0 ) return " 192.168.1.35 " ;
176+ return std::string ( inet_ntoa (addr)) ;
158177 }
159178 return " 127.0.0.1" ;
160179}
@@ -180,12 +199,6 @@ bool try_connect(const std::string& ip, int port) {
180199 res = (v == 0 ) ? 0 : -1 ;
181200 } else res = -1 ;
182201 }
183-
184- if (res != 0 && g_dev_mode) {
185- char err[128 ];
186- snprintf (err, sizeof (err), " \x1b [2m[DEBUG] Connect %s:%d failed (%d)\x1b [0m" , ip.c_str (), port, errno);
187- add_app_log (err);
188- }
189202
190203 fcntl (sock, F_SETFL, flags);
191204 close (sock);
@@ -236,55 +249,68 @@ void fetch_offline_boot_logs() {
236249 add_app_log (entry);
237250 }
238251 fclose (f);
239- // Do NOT remove file yet, keep for diagnostics if needed
252+ remove ( " sdmc:/ha_sysmodule_boot.log " );
240253 }
241254}
242255
243256void draw_ui (const std::string& latest_ver, bool checking_update, bool sysmodule_active, u64 loop_count) {
244- printf (" \x1b [1;1H" );
245- printf (" \x1b [41m\x1b [1;37m HOME ASSISTANT SWITCH v%s \x1b [0m\x1b [K\n " , APP_VERSION);
246- printf (" \x1b [2m (c) 2026 FaserF | https://github.com/FaserF/ha-NintendoSwitchCFW\x1b [0m\x1b [K\n\n " );
257+ printf (" \x1b [H" ); // Home
258+ printf (" \x1b [36m┌──────────────────────────────────────────────────────────────────────────┐\x1b [0m\x1b [K\n " );
259+ printf (" \x1b [36m│\x1b [0m\x1b [1;37m HOME ASSISTANT SWITCH v%-10s \x1b [0m\x1b [36m│\x1b [0m\x1b [K\n " , APP_VERSION);
260+ printf (" \x1b [36m├───────────────────────────────┬──────────────────────────────────────────┤\x1b [0m\x1b [K\n " );
261+
262+ // Left Pane: System Status
263+ printf (" \x1b [36m│\x1b [0m \x1b [1;34m[ SYSTEM STATUS ]\x1b [0m \x1b [36m│\x1b [0m \x1b [1;34m[ UPDATES & CONFIG ]\x1b [0m \x1b [36m│\x1b [0m\x1b [K\n " );
264+
265+ printf (" \x1b [36m│\x1b [0m Status: %-18s \x1b [36m│\x1b [0m " , sysmodule_active ? " \x1b [1;32mACTIVE\x1b [0m" : " \x1b [1;31mINACTIVE\x1b [0m" );
266+ if (checking_update) printf (" \x1b [5;33mChecking for updates...\x1b [0m " );
267+ else if (latest_ver == " " ) printf (" \x1b [2mUpdate check pending... (X) \x1b [0m " );
268+ else if (latest_ver != " none" && latest_ver != " error" ) {
269+ if (latest_ver != APP_VERSION) printf (" \x1b [1;42m\x1b [37m NEW v%-6s AVAILABLE! (Y) \x1b [0m " , latest_ver.c_str ());
270+ else printf (" \x1b [2mLatest version active (v%-6s) \x1b [0m" , latest_ver.c_str ());
271+ } else printf (" \x1b [31mUpdate check failed \x1b [0m " );
272+ printf (" \x1b [36m│\x1b [0m\x1b [K\n " );
247273
248- printf (" \x1b [1;36m[ SYSTEM STATUS ]\x1b [0m\x1b [K\n " );
249- printf (" Status: %s\x1b [K\n " , sysmodule_active ? " \x1b [1;32mACTIVE\x1b [0m" : " \x1b [1;31mINACTIVE\x1b [0m" );
250274 u32 ip = 0 ;
275+ struct in_addr addr;
251276 if (R_SUCCEEDED (nifmGetCurrentIpAddress (&ip)) && ip != 0 ) {
252- struct in_addr addr; addr.s_addr = ip;
253- printf (" IP Address: \x1b [1;32m%s\x1b [0m\x1b [K\n " , inet_ntoa (addr));
254- } else printf (" IP Address: \x1b [1;31mDisconnected\x1b [0m\x1b [K\n " );
277+ addr.s_addr = ip;
278+ printf (" \x1b [36m│\x1b [0m IP: \x1b [1;32m%-15s\x1b [0m \x1b [36m│\x1b [0m " , inet_ntoa (addr));
279+ } else {
280+ printf (" \x1b [36m│\x1b [0m IP: \x1b [1;31mDisconnected\x1b [0m \x1b [36m│\x1b [0m " );
281+ }
282+ printf (" Port: \x1b [1m%-5d\x1b [0m \x1b [36m│\x1b [0m\x1b [K\n " , ConfigManager::getInstance ().getPort ());
255283
256284 NifmInternetConnectionStatus net_status;
285+ const char * net_s = " Unknown" ;
257286 if (R_SUCCEEDED (nifmGetInternetConnectionStatus (NULL , NULL , &net_status))) {
258- const char * s = (net_status == NifmInternetConnectionStatus_Connected) ? " Online" : " Limited/Off" ;
259- printf (" Net Status: \x1b [1m%s\x1b [0m\x1b [K\n " , s);
287+ net_s = (net_status == NifmInternetConnectionStatus_Connected) ? " \x1b [1;32mOnline\x1b [0m" : " \x1b [1;31mOffline\x1b [0m" ;
260288 }
261- printf (" \x1b [K\n " );
262-
263- printf (" \x1b [1;36m[ CONFIGURATION ]\x1b [0m\x1b [K\n " );
264- printf (" Port: \x1b [1m%d\x1b [0m | Token: \x1b [1;33m%s\x1b [0m\x1b [K\n\n " ,
265- ConfigManager::getInstance ().getPort (), ConfigManager::getInstance ().getApiToken ()[0 ] ? ConfigManager::getInstance ().getApiToken () : " NONE" );
289+ printf (" \x1b [36m│\x1b [0m Network: %-25s \x1b [36m│\x1b [0m " , net_s);
290+ printf (" Token: \x1b [1;33m%-15s\x1b [0m \x1b [36m│\x1b [0m\x1b [K\n " , ConfigManager::getInstance ().getApiToken ()[0 ] ? ConfigManager::getInstance ().getApiToken () : " MISSING" );
266291
267- printf (" \x1b [1;36m[ UPDATES ]\x1b [0m\x1b [K\n " );
268- if (checking_update) printf (" \x1b [5;33mChecking...\x1b [0m\x1b [K\n " );
269- else if (latest_ver == " " ) printf (" \x1b [2mUpdate check pending... (X) to Check\x1b [0m\x1b [K\n " );
270- else if (latest_ver != " none" && latest_ver != " error" ) {
271- if (latest_ver != APP_VERSION) {
272- if (APP_VERSION > latest_ver) printf (" \x1b [1;32mDEV VERSION (Ahead of GitHub v%s)\x1b [0m\x1b [K\n " , latest_ver.c_str ());
273- else printf (" \x1b [1;42m\x1b [37m NEW v%s AVAILABLE! \x1b [0m (Y)\x1b [K\n " , latest_ver.c_str ());
274- } else printf (" \x1b [2mLatest version active.\x1b [0m\x1b [K\n " );
275- } else printf (" \x1b [2mUpdate check failed/skipped.\x1b [0m\x1b [K\n " );
276- printf (" \x1b [K\n " );
277-
278- printf (" \x1b [1;36m[ SYSTEM LOGS ]\x1b [0m\x1b [K\n " );
279- if (g_app_logs.empty ()) printf (" Waiting for bridge...\x1b [K\n " );
280- else {
292+ printf (" \x1b [36m├───────────────────────────────┴──────────────────────────────────────────┤\x1b [0m\x1b [K\n " );
293+ printf (" \x1b [36m│\x1b [0m \x1b [1;34m[ SYSTEM LOGS ]\x1b [0m \x1b [36m│\x1b [0m\x1b [K\n " );
294+
295+ if (g_app_logs.empty ()) {
296+ for (int i=0 ; i<10 ; i++) printf (" \x1b [36m│\x1b [0m %-72s \x1b [36m│\x1b [0m\x1b [K\n " , i == 0 ? " Waiting for sysmodule bridge..." : " " );
297+ } else {
281298 size_t start = (g_app_logs.size () > 10 ) ? g_app_logs.size () - 10 : 0 ;
282- for (size_t i = start; i < g_app_logs.size (); i++) printf (" %s\x1b [K\n " , g_app_logs[i].c_str ());
299+ for (size_t i = 0 ; i < 10 ; i++) {
300+ printf (" \x1b [36m│\x1b [0m " );
301+ if (start + i < g_app_logs.size ()) {
302+ printf (" %s" , g_app_logs[start + i].c_str ());
303+ printf (" \x1b [75G\x1b [36m│\x1b [0m\x1b [K\n " );
304+ } else {
305+ printf (" %-72s \x1b [36m│\x1b [0m\x1b [K\n " , " " );
306+ }
307+ }
283308 }
284- for (int i=0 ; i<3 ; i++) printf (" \x1b [K\n " );
285- printf (" \x1b [1;34m----------------------------------------------------\x1b [0m\x1b [K\n " );
286- printf (" (ZL)Reload (ZR)Reset (X)Update (Y)Install (+)Exit (-)Dev\x1b [K\n " );
287- printf (" \x1b [1;34m----------------------------------------------------\x1b [0m\x1b [K\n " );
309+
310+ printf (" \x1b [36m└──────────────────────────────────────────────────────────────────────────┘\x1b [0m\x1b [K\n " );
311+ printf (" \x1b [1;37m(X)Check (Y)Update/Install (ZR)Reset (-)DevMode (+)Exit\x1b [0m\x1b [K\n " );
312+ if (g_dev_mode) printf (" \x1b [45m\x1b [1;37m DEV MODE ACTIVE \x1b [0m UDP Broadcast on Port 2828\x1b [K\n " );
313+ else printf (" \x1b [K\n " );
288314}
289315
290316int main (int argc, char **argv) {
0 commit comments