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

@ -1,7 +1,7 @@
/*
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
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
@ -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 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;
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;
@ -80,9 +115,9 @@ namespace MCGalaxy {
}
class Response {
public string[][] errors;
public string response;
public string status;
public string[][] errors;
public string response;
public string status;
}
}
}

View File

@ -1,7 +1,7 @@
/*
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
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
@ -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

@ -1,38 +1,41 @@
/*
Copyright 2012 MCForge
Copyright 2012 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
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();
/// <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> Called when a response is recieved. </summary>
/// <param name="resonse">The resonse.</param>
void OnResponse(string resonse);
}
namespace MCGalaxy {
public interface IBeat {
/// <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>
void OnResponse(string resonse);
}
}