-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRealWeather.cs
More file actions
156 lines (135 loc) · 5.67 KB
/
RealWeather.cs
File metadata and controls
156 lines (135 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
using System.Collections.Generic;
using System.Configuration;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using System.Net.Http;
using Newtonsoft.Json;
using System.Linq;
using System;
using System.Threading;
namespace RealWeather;
internal static class ModInfo
{
internal const string Guid = "me.pocke.real-weather";
internal const string Name = "Real Weather";
internal const string Version = "1.0.0";
}
[BepInPlugin(ModInfo.Guid, ModInfo.Name, ModInfo.Version)]
internal class RealWeather : BaseUnityPlugin
{
public bool IsSyncNeeded { get; private set; } = false;
public List<Weather.Forecast> forecasts = new List<Weather.Forecast>();
static string apiUrlBase = "https://api.open-meteo.com/v1/forecast";
private CancellationTokenSource cancellationTokenSource;
private void Awake()
{
Settings.latitude = Config.Bind("Settings", "Latitude", 35.6895, "Latitude for weather data (default: Tokyo)");
Settings.longitude = Config.Bind("Settings", "Longitude", 139.6917, "Longitude for weather data (default: Tokyo)");
cancellationTokenSource = new CancellationTokenSource();
StartFetchingWeather(cancellationTokenSource.Token);
Logger.LogInfo("RealWeather Mod is loaded!");
}
private void Update()
{
if (!EClass.core.IsGameStarted)
{
return;
}
if (IsSyncNeeded)
{
int size = forecasts.Count;
EClass.world.weather.forecasts = forecasts;
forecasts = new List<Weather.Forecast>();
EClass.world.weather.SetConditionFromForecast();
Logger.LogInfo($"Weather data synced: {size} entries.");
IsSyncNeeded = false;
}
}
private void OnDestroy()
{
try {
cancellationTokenSource.Cancel();
}
finally {
cancellationTokenSource.Dispose();
}
}
private async void StartFetchingWeather(CancellationToken token)
{
while (!token.IsCancellationRequested) {
if (IsSyncNeeded)
{
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(1));
continue;
}
try
{
string url = $"{apiUrlBase}?latitude={Settings.Latitude}&longitude={Settings.Longitude}&hourly=weather_code";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Add("User-Agent", $"RealWeatherMod/{ModInfo.Version}");
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
string jsonResponse = await response.Content.ReadAsStringAsync();
var weatherData = Newtonsoft.Json.JsonConvert.DeserializeObject<ApiResponse>(jsonResponse);
if (weatherData != null && weatherData.Hourly != null && weatherData.Hourly.WeatherCode != null && weatherData.Hourly.WeatherCode.Count() > 0)
{
List<int> wmoCodes = weatherData.Hourly.WeatherCode;
forecasts = new List<Weather.Forecast>();
Weather.Condition? currentCondition = null;
int currentDuration = 0;
foreach (int wmoCode in wmoCodes)
{
Weather.Condition condition = WeatherCode.GetWeatherConditionFromWMOCode(wmoCode);
if (currentCondition == condition)
{
currentDuration++;
}
else
{
if (currentCondition != null)
{
forecasts.Add(new Weather.Forecast
{
duration = currentDuration,
condition = currentCondition.Value,
});
}
currentCondition = condition;
currentDuration = 1;
}
}
// Add the last forecast
if (currentCondition != null)
{
forecasts.Add(new Weather.Forecast
{
duration = currentDuration,
condition = currentCondition.Value,
});
}
IsSyncNeeded = true;
Logger.LogInfo($"Updated forecasts: {forecasts.Count} entries.");
}
else
{
Logger.LogError("Failed to parse weather data:" + jsonResponse);
}
}
else
{
Logger.LogError($"Failed to fetch weather data: {response.StatusCode}");
}
}
}
catch (System.Exception ex)
{
Logger.LogError($"Exception while fetching weather data: {ex.Message}");
}
await System.Threading.Tasks.Task.Delay(TimeSpan.FromMinutes(15));
}
}
}