From b537b4bc0f45d292107d1d9287d18ec3c640da0c Mon Sep 17 00:00:00 2001 From: ImBenji Date: Tue, 5 Aug 2025 15:08:36 +0100 Subject: [PATCH] Add geolocation data retrieval and update server registration with geolocation information --- lib/core/utils.dart | 137 +++++++++++++++++++++++++++++++ lib/services/server_service.dart | 9 +- 2 files changed, 145 insertions(+), 1 deletion(-) diff --git a/lib/core/utils.dart b/lib/core/utils.dart index bb764bc..3959bb7 100644 --- a/lib/core/utils.dart +++ b/lib/core/utils.dart @@ -3,6 +3,143 @@ import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart' as http; +class GeolocationData { + final String ip; + final String network; + final String version; + final String city; + final String region; + final String regionCode; + final String country; + final String countryName; + final String countryCode; + final String countryCodeIso3; + final String countryCapital; + final String countryTld; + final String continentCode; + final bool inEu; + final String postal; + final double latitude; + final double longitude; + final String timezone; + final String utcOffset; + final String countryCallingCode; + final String currency; + final String currencyName; + final String languages; + final double countryArea; + final int countryPopulation; + final String asn; + final String org; + + GeolocationData({ + required this.ip, + required this.network, + required this.version, + required this.city, + required this.region, + required this.regionCode, + required this.country, + required this.countryName, + required this.countryCode, + required this.countryCodeIso3, + required this.countryCapital, + required this.countryTld, + required this.continentCode, + required this.inEu, + required this.postal, + required this.latitude, + required this.longitude, + required this.timezone, + required this.utcOffset, + required this.countryCallingCode, + required this.currency, + required this.currencyName, + required this.languages, + required this.countryArea, + required this.countryPopulation, + required this.asn, + required this.org, + }); + + factory GeolocationData.fromJson(Map json) { + return GeolocationData( + ip: json['ip'], + network: json['network'], + version: json['version'], + city: json['city'], + region: json['region'], + regionCode: json['region_code'], + country: json['country'], + countryName: json['country_name'], + countryCode: json['country_code'], + countryCodeIso3: json['country_code_iso3'], + countryCapital: json['country_capital'], + countryTld: json['country_tld'], + continentCode: json['continent_code'], + inEu: json['in_eu'], + postal: json['postal'], + latitude: json['latitude'].toDouble(), + longitude: json['longitude'].toDouble(), + timezone: json['timezone'], + utcOffset: json['utc_offset'], + countryCallingCode: json['country_calling_code'], + currency: json['currency'], + currencyName: json['currency_name'], + languages: json['languages'], + countryArea: json['country_area'].toDouble(), + countryPopulation: json['country_population'], + asn: json['asn'], + org: json['org'], + ); + } + + Map toJson() { + return { + 'ip': ip, + 'network': network, + 'version': version, + 'city': city, + 'region': region, + 'region_code': regionCode, + 'country': country, + 'country_name': countryName, + 'country_code': countryCode, + 'country_code_iso3': countryCodeIso3, + 'country_capital': countryCapital, + 'country_tld': countryTld, + 'continent_code': continentCode, + 'in_eu': inEu, + 'postal': postal, + 'latitude': latitude, + 'longitude': longitude, + 'timezone': timezone, + 'utc_offset': utcOffset, + 'country_calling_code': countryCallingCode, + 'currency': currency, + 'currency_name': currencyName, + 'languages': languages, + 'country_area': countryArea, + 'country_population': countryPopulation, + 'asn': asn, + 'org': org, + }; + } +} + +// Get the geolocation data of the device using its IP address. +Future getGeolocationData() async { + // Get the IP address of the server. https://ipapi.co/json/ + var response = await http.get(Uri.parse('https://ipapi.co/json/')); + if (response.statusCode == 200) { + var data = jsonDecode(response.body); + return GeolocationData.fromJson(data); + } else { + throw Exception('Failed to get geolocation data'); + } +} + +@deprecated /// Get the current WAN IP address of the device. Future getWanIp() async { // Get the IP address of the server. https://api.ipify.org?format=json diff --git a/lib/services/server_service.dart b/lib/services/server_service.dart index 5c38ede..360f014 100644 --- a/lib/services/server_service.dart +++ b/lib/services/server_service.dart @@ -4,7 +4,10 @@ import 'package:waylume_server/core/utils.dart'; class ServerService { static Future registerServer() async { - String ip = "${await getWanIp()}:${fromEnivronment("EXTERNAL_PORT") ?? "3000"}"; + + GeolocationData geolocationData = await getGeolocationData(); + + String ip = "${geolocationData.ip}:${fromEnivronment("EXTERNAL_PORT") ?? "3000"}"; var existsCheck = await SUPABASE_CLIENT .from("waylume_servers") @@ -19,6 +22,10 @@ class ServerService { "id": fromEnivronment('SERVER_ID')!, "last_heartbeat": DateTime.now().toUtc().toIso8601String(), "host_ip": ip, + "geolocation": { + "country_code": geolocationData.continentCode, + "city": geolocationData.city, + } }); } }