Introduce (possible) fix for issue with using ipv6 instead of ipv4 address when POSTing a heartbeat to classicube.net.

This commit is contained in:
UnknownShadow200 2016-07-21 18:48:44 +10:00
parent ebd755dd77
commit 36e7236588
4 changed files with 88 additions and 53 deletions

View File

@ -514,6 +514,7 @@
<Compile Include="Levels\Physics\TrainPhysics.cs" /> <Compile Include="Levels\Physics\TrainPhysics.cs" />
<Compile Include="Levels\Physics\TntPhysics.cs" /> <Compile Include="Levels\Physics\TntPhysics.cs" />
<Compile Include="Levels\Physics\ZombiePhysics.cs" /> <Compile Include="Levels\Physics\ZombiePhysics.cs" />
<Compile Include="Network\Heart.cs" />
<Compile Include="Network\IRCBot.cs" /> <Compile Include="Network\IRCBot.cs" />
<Compile Include="Network\LevelChunkStream.cs" /> <Compile Include="Network\LevelChunkStream.cs" />
<Compile Include="Player\Entities.cs" /> <Compile Include="Player\Entities.cs" />
@ -566,7 +567,6 @@
<Compile Include="GlobalSuppressions.cs" /> <Compile Include="GlobalSuppressions.cs" />
<Compile Include="Network\IBeat.cs" /> <Compile Include="Network\IBeat.cs" />
<Compile Include="Levels\Level.cs" /> <Compile Include="Levels\Level.cs" />
<Compile Include="Server\Extra\Heart.cs" />
<Compile Include="Server\Logger.cs" /> <Compile Include="Server\Logger.cs" />
<Compile Include="Player\Player.cs" /> <Compile Include="Player\Player.cs" />
<Compile Include="Server\Extra\ProfanityFilter.cs"> <Compile Include="Server\Extra\ProfanityFilter.cs">

View File

@ -1,7 +1,7 @@
/* /*
Copyright 2012 MCForge Copyright 2012 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
@ -17,17 +17,48 @@
*/ */
using System; using System;
using System.IO; using System.IO;
using System.Net;
using System.Net.Sockets;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace MCGalaxy { namespace MCGalaxy {
public sealed class ClassiCubeBeat : IBeat { public sealed class ClassiCubeBeat : IBeat {
public string URL { get { return "http://www.classicube.net/heartbeat.jsp"; } } string url = "http://www.classicube.net/heartbeat.jsp";
public string URL { get { return url; } }
public bool Persistance { get { return true; } } public bool Persistance { get { return true; } }
public void Init() {
try {
IPAddress[] addresses = Dns.GetHostAddresses("www.classicube.net");
EnsureIPv4Url(addresses);
} catch (Exception ex) {
Server.s.Log("Error while trying to retrieve DNS information for classicube.net");
Server.ErrorLog(ex);
}
}
// classicube.net only supports ipv4 servers, so we need to make
// sure we are using its ipv4 address when POSTing heartbeats
void EnsureIPv4Url(IPAddress[] addresses) {
bool useIPv6 = false;
IPAddress firstIPv4 = null;
foreach (IPAddress ip in addresses) {
AddressFamily family = ip.AddressFamily;
if (family == AddressFamily.InterNetworkV6)
useIPv6 = true;
if (family == AddressFamily.InterNetwork && firstIPv4 == null)
firstIPv4 = ip;
}
if (!useIPv6 || firstIPv4 == null) return;
url = "http://" + firstIPv4 + ":80/heartbeat.jsp";
}
public string Prepare() { public string PrepareBeat() {
string name = Server.name; string name = Server.name;
Server.zombie.OnHeartbeat(ref name); Server.zombie.OnHeartbeat(ref name);
Server.lava.OnHeartbeat(ref name); Server.lava.OnHeartbeat(ref name);
@ -51,6 +82,10 @@ namespace MCGalaxy {
return count; return count;
} }
public void OnRequest(HttpWebRequest request) {
request.Host = "www.classicube.net";
}
bool foundUrl = false; bool foundUrl = false;
public void OnResponse(string line) { public void OnResponse(string line) {
if (String.IsNullOrEmpty(line.Trim())) return; if (String.IsNullOrEmpty(line.Trim())) return;
@ -80,9 +115,9 @@ namespace MCGalaxy {
} }
class Response { class Response {
public string[][] errors; public string[][] errors;
public string response; public string response;
public string status; public string status;
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
Copyright 2012 MCForge Copyright 2012 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
@ -63,16 +63,16 @@ namespace MCGalaxy {
} }
CanBeat = true; CanBeat = true;
for (int i = 0; i < Beats.Length; i++) for (int i = 0; i < Beats.Length; i++) {
Beats[i].Init();
Pump(Beats[i]); Pump(Beats[i]);
}
} }
/// <summary> Pumps the specified beat. </summary> /// <summary> Pumps the specified beat. </summary>
/// <param name="beat">The beat.</param>
/// <returns></returns>
public static void Pump(IBeat beat) { public static void Pump(IBeat beat) {
if(!CanBeat) return; if (!CanBeat) return;
byte[] data = Encoding.ASCII.GetBytes(beat.Prepare()); byte[] data = Encoding.ASCII.GetBytes(beat.PrepareBeat());
for (int i = 0; i < MAX_RETRIES; i++) { for (int i = 0; i < MAX_RETRIES; i++) {
try { try {
@ -82,20 +82,18 @@ namespace MCGalaxy {
req.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); req.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
req.Timeout = 15000; req.Timeout = 15000;
req.ContentLength = data.Length; req.ContentLength = data.Length;
beat.OnRequest(req);
using (var w = req.GetRequestStream()) { using (var w = req.GetRequestStream()) {
w.Write(data, 0, data.Length); w.Write(data, 0, data.Length);
if (Server.logbeat) Server.s.Log("Beat " + beat + " was sent");
if (Server.logbeat)
Server.s.Log("Beat " + beat.ToString() + " was sent");
} }
using (var r = new StreamReader(req.GetResponse().GetResponseStream())) { using (var r = new StreamReader(req.GetResponse().GetResponseStream())) {
string read = r.ReadToEnd().Trim(); string read = r.ReadToEnd().Trim();
beat.OnResponse(read); beat.OnResponse(read);
if (Server.logbeat) if (Server.logbeat) Server.s.Log("Beat: \"" + read + "\" was recieved");
Server.s.Log("Beat: \"" + read + "\" was recieved");
} }
return; return;
} catch { } catch {
@ -103,8 +101,7 @@ namespace MCGalaxy {
} }
} }
if (Server.logbeat) if (Server.logbeat) Server.s.Log("Beat: " + beat + " failed.");
Server.s.Log("Beat: " + beat.ToString() + " failed.");
} }
} }
} }

View File

@ -1,38 +1,41 @@
/* /*
Copyright 2012 MCForge Copyright 2012 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS" software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
namespace MCGalaxy using System.Net;
{
public interface IBeat
{
/// <summary> Gets or sets the URL. </summary>
/// <value> The URL. </value>
string URL {get; }
/// <summary> Prepares this instance. </summary> namespace MCGalaxy {
/// <returns></returns> public interface IBeat {
string Prepare();
/// <summary> Gets the URL. </summary>
/// <summary> Gets a value indicating whether this <see cref="IBeat"/> is persistance. </summary> string URL { get; }
/// <value> <c>true</c> if persistance; otherwise, <c>false</c>. </value>
bool Persistance {get; } /// <summary> Gets whether this IBeat has periodically repeating beats. </summary>
bool Persistance { get; }
/// <summary> Called when a response is recieved. </summary>
/// <param name="resonse">The resonse.</param> /// <summary> Initialises persistent data for this beat instance. </summary>
void OnResponse(string resonse); void Init();
}
/// <summary> Prepares the data for the next beat of this this instance. </summary>
string PrepareBeat();
/// <summary> Called when a response is recieved. </summary>
void OnRequest(HttpWebRequest request);
/// <summary> Called when a response is recieved. </summary>
void OnResponse(string resonse);
}
} }