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

View File

@ -17,17 +17,48 @@
*/
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using Newtonsoft.Json;
namespace MCGalaxy {
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 string Prepare() {
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 PrepareBeat() {
string name = Server.name;
Server.zombie.OnHeartbeat(ref name);
Server.lava.OnHeartbeat(ref name);
@ -51,6 +82,10 @@ namespace MCGalaxy {
return count;
}
public void OnRequest(HttpWebRequest request) {
request.Host = "www.classicube.net";
}
bool foundUrl = false;
public void OnResponse(string line) {
if (String.IsNullOrEmpty(line.Trim())) return;

View File

@ -63,16 +63,16 @@ namespace MCGalaxy {
}
CanBeat = true;
for (int i = 0; i < Beats.Length; i++)
for (int i = 0; i < Beats.Length; i++) {
Beats[i].Init();
Pump(Beats[i]);
}
}
/// <summary> Pumps the specified beat. </summary>
/// <param name="beat">The beat.</param>
/// <returns></returns>
public static void Pump(IBeat beat) {
if(!CanBeat) return;
byte[] data = Encoding.ASCII.GetBytes(beat.Prepare());
if (!CanBeat) return;
byte[] data = Encoding.ASCII.GetBytes(beat.PrepareBeat());
for (int i = 0; i < MAX_RETRIES; i++) {
try {
@ -82,20 +82,18 @@ namespace MCGalaxy {
req.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
req.Timeout = 15000;
req.ContentLength = data.Length;
beat.OnRequest(req);
using (var w = req.GetRequestStream()) {
w.Write(data, 0, data.Length);
if (Server.logbeat)
Server.s.Log("Beat " + beat.ToString() + " was sent");
if (Server.logbeat) Server.s.Log("Beat " + beat + " was sent");
}
using (var r = new StreamReader(req.GetResponse().GetResponseStream())) {
string read = r.ReadToEnd().Trim();
beat.OnResponse(read);
if (Server.logbeat)
Server.s.Log("Beat: \"" + read + "\" was recieved");
if (Server.logbeat) Server.s.Log("Beat: \"" + read + "\" was recieved");
}
return;
} catch {
@ -103,8 +101,7 @@ namespace MCGalaxy {
}
}
if (Server.logbeat)
Server.s.Log("Beat: " + beat.ToString() + " failed.");
if (Server.logbeat) Server.s.Log("Beat: " + beat + " failed.");
}
}
}

View File

@ -15,24 +15,27 @@
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
namespace MCGalaxy
{
public interface IBeat
{
/// <summary> Gets or sets the URL. </summary>
/// <value> The URL. </value>
string URL {get; }
using System.Net;
/// <summary> Prepares this instance. </summary>
/// <returns></returns>
string Prepare();
namespace MCGalaxy {
public interface IBeat {
/// <summary> Gets a value indicating whether this <see cref="IBeat"/> is persistance. </summary>
/// <value> <c>true</c> if persistance; otherwise, <c>false</c>. </value>
bool Persistance {get; }
/// <summary> Gets the URL. </summary>
string URL { get; }
/// <summary> Gets whether this IBeat has periodically repeating beats. </summary>
bool Persistance { get; }
/// <summary> Initialises persistent data for this beat instance. </summary>
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>
/// <param name="resonse">The resonse.</param>
void OnResponse(string resonse);
}
}