Minecraft PC IP: play.cubecraft.net
Status
Not open for further replies.

Max ♠

Forum Expert
Feb 20, 2016
1,420
2,940
344
24
North pole
I got bored yesterday, here's another forum addon which may be usefull to some people..

What the script does:
upload_2017-8-11_20-53-4.png


(Got the idea from https://www.cubecraft.net/threads/suggestion-report-a-player-sidebar.177726/ )

How to install
Chrome - Click
Firefox - Click
Opera - Click
(Just create a new file for each script of the 3 scripts, to use the script made by @MagnificentSpam install Tampermonkey instead of Violentmonkey)

After I posted this @MagnificentSpam made an adaption of my script which works way better, I would recommend using his solution.
Code:
// ==UserScript==
// @name Cubecraft Report Statistics
// @namespace Landviz' scripts
// @grant none
// @match https://www.cubecraft.net/
// @match https://www.cubecraft.net/forums/
// ==/UserScript==

function getCookie(cname) { // A function to eaasily check cookies
    var name = cname + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i <ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

var updateTime = 30; // Time before the report stats try to update again in minutes

var reportsOpen = Number(getCookie('openReports'));

if(reportsOpen > 9) {
    reportsOpen = "9+";
}

if(getCookie('handledReports') != "") {
    var date = new Date();
    var time = date.getTime();
    document.querySelector('.styliumMainSidebar').innerHTML += '<div class="section widget_ForumStats" id="widget_4"><div class="secondaryContent statsList" style="background:#ffffff;"><h3>Reporting Statistics</h3><div class="pairsJustified">    <dl class="discussionCount"><dt>Successful reports:</dt><dd>' + getCookie('handledReports') + '</dd></dl><dl class="messageCount"><dt>Open reports:</dt><dd>' + reportsOpen + '</dd></dl><dl class="mostCount"><dt>Last update:</dt><dd>' + timeConverter(getCookie('updateTime')/1000) + '</dd></dl><dl><dd><a href="https://reports.cubecraft.net/report?refresh" target="_blank" onclick="setTimeout(function(){ location.reload(); }, 3000);">Update now</a></dd></dl></div></div></div>';
    var timeDifference = time - getCookie('updateTime');
    var updateTimeConv = updateTime*60*1000;
    if(timeDifference > updateTimeConv) {
        updateStats();
    }
    setInterval(function() {
        if(!document.hasFocus()) {
            location.reload();
        }
    }, 300000);
} else {
    updateStats();
}

function timeConverter(UNIX_timestamp){ // Unix to normal time
    var a = new Date(UNIX_timestamp * 1000);
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    var year = a.getFullYear();
    var month = months[a.getMonth()];
    var date = a.getDate();
    var hour = a.getHours();
    if(hour < 10) {
        hour = "0" + hour;
    }
    var min = a.getMinutes();
    if(min < 10) {
        min = "0" + min;
    }
    var sec = a.getSeconds();
    if(sec < 10) {
        sec = "0" + sec;
    }
    var time = hour + ':' + min + ':' + sec + ', ' + month + ' ' + date;
    return time;
}

function updateStats() {
    window.open('https://reports.cubecraft.net/report?refresh', '_blank');
    setTimeout(function(){ location.reload(); }, 3000);
}

Code:
// ==UserScript==
// @name Cubecraft Var Retreiver
// @namespace Landviz' scripts
// @grant none
// @match https://www.cubecraft.net/?*
// ==/UserScript==

var input = window.location.href.substring(27).split(';');


function setCookie(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+ d.toUTCString();
    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

var date = new Date();
var time = date.getTime();

setCookie('handledReports', input[0], 365);
setCookie('openReports', input[1], 365);
setCookie('updateTime', time, 365);

window.close();

Code:
// ==UserScript==
// @name Reports Updater
// @namespace Landviz' scripts
// @grant none
// @match https://reports.cubecraft.net/report?refresh
// ==/UserScript==

var reports = document.querySelector('span.handled').innerHTML;
var reportsOpen = document.querySelectorAll('span[style="color: #FFA500"]').length;

console.log(reportsOpen);

var newUrl = "https://www.cubecraft.net/?" + reports + ";" + reportsOpen;

window.location.href = newUrl;

Greasyfork links:
https://greasyfork.org/en/scripts/32219-cubecraft-report-statistics
https://greasyfork.org/en/scripts/32222-cubecraft-var-retreiver
https://greasyfork.org/en/scripts/32223-reports-updater
(all 3 are required)

It saves the statistics in cookies and tries to update the statistics on page load or if the browser tab is not in focus. If the statistics have been updated in the past 30 minutes it will not update them automatically. You can use the "update now" to update the statistics manually.

Updating the script opens up the report site in a new tab, you then get redirected, after that the tab closes. (if your internet doesnt manage to open 2 links in 3 seconds it might open another tab and try again)

(Make sure you're logged into the report site, else it wont work)

If you're interested in how the script works:
When you open up "https://cubecraft.net/" or "https://cubecraft.net/forums" it checks if you have cookies with the required data to fill in the menu. If you have the data required, it checks if the data has been updated in the past 30 minutes. If the data hasnt been updated the past 30 minutes or you don't have the cookies required, it opens up a new tab "https://reports.cubecraft.net/report?refresh", the "?refresh" part is what the third script requires to be activated, it get's the amount of successful reports and counts how many open reports you have. It will then redirect you to "https://cubecraft.net/?7;2", 7 being the amount of successful reports, 2 being the amount of open reports. Thanks to "?" script 2 activates and creates the cookies required for script 1, tab gets closed after the creation of the cookies & the original tab get's refreshed.

the setCookie() & getCookie functions are not written by me. Got them from W3schools

(I don't have acces to any database to get the data from so I have to do it this way instead..)
Use the Tampermonkey addon & create a new script. Enter the following:
Code:
// ==UserScript==
// @name Cubecraft Report Thing
// @namespace de.rasmusantons
// @require https://www.cubecraft.net/js/jquery/jquery-1.11.0.min.js
// @include https://www.cubecraft.net/
// @include https://www.cubecraft.net/forums/
// @version 1
// @description Adaption of https://www.cubecraft.net/threads/reporting-statistics.195329/
// @grant GM_xmlhttpRequest
// ==/UserScript==

var UPDATE_INTERVAL = 5; // Time before the report stats try to update again in minutes

function timeConverter(UNIX_timestamp){ // Unix to normal time
    var a = new Date(UNIX_timestamp);
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    var month = months[a.getMonth()];
    var date = a.getDate();
    var hour = a.getHours();
    if(hour < 10)
        hour = "0" + hour;
    var min = a.getMinutes();
    if(min < 10)
        min = "0" + min;
    var sec = a.getSeconds();
    if(sec < 10)
        sec = "0" + sec;
    return hour + ':' + min + ':' + sec + ', ' + month + ' ' + date;
}

function drawWidget(handledReports, openReports, updateTime) {
    document.querySelectorAll('.widget_ReportStats').forEach(function(e) {e.remove()});
    if(openReports > 9)
        openReports = "10+";
    $('.styliumMainSidebar').append('<div class="section widget_ForumStats widget_ReportStats" id="widget_4">'
            + '<div class="secondaryContent statsList" style="background:#ffffff;">'
            + '<h3>Reporting Statistics</h3><div class="pairsJustified">'
            + '<dl class="discussionCount"><dt>Successful reports:</dt><dd>' + handledReports + '</dd></dl>'
            + '<dl class="messageCount"><dt>Open reports:</dt><dd>' + openReports + '</dd></dl>'
            + '<dl class="mostCount"><dt>Last update:</dt><dd>' + timeConverter(updateTime) + '</dd></dl>'
            + '<dl><dd><a id="updateStatsLink">Update now</a></dd></dl>'
            + '</div></div></div>');
    $('#updateStatsLink').click(updateStats);
}

function updateStats() {
    GM_xmlhttpRequest({
        method: "GET",
        url: "https://reports.cubecraft.net/report",
        onload: function(response) {
            var handledReports = response.responseText.match(/<span class="handled">(\d+)<\/span>/)[1];
            var openReports = (response.responseText.match(/<span style="color: #FFA500">/g) || []).length;
            drawWidget(handledReports, openReports, new Date().getTime());
        }
    });
}

$(document).ready(function() {
    updateStats();
    setInterval(updateStats, UPDATE_INTERVAL * 60 * 1000);
});

If you have an idea of what I could make the next time I get bored, please let me know :3
 
Last edited:

Max ♠

Forum Expert
Feb 20, 2016
1,420
2,940
344
24
North pole
But I think there is still a small bugg, it says I have 10 open reports, but I have 56 open reports. (Counted them)
It only checks the first page, it's possible to check multiple but overall not really worth it considering the time it would take me to implement this.

I'll update the code to say 9+ instead of 10
 

MagnificentSpam

Forum Expert
Mar 16, 2016
2,306
2,238
298
That is pretty neat.
When looking at the source code I though there must be a less hacky way to do this, something like
Code:
$.ajax({
    type: 'GET',
    url: 'https://reports.cubecraft.net/report',
    xhrFields: {
        withCredentials: true
    }
});
to avoid opening the new window, setting the fake get parameters and setting and reading the cookie.
Sadly (I guess you might have tried that yourself) that doesn't work because browsers block XHttpRequests from different domains (even sub domains) if the Access-Allow-Control-Origin header isn't set correctly.

So after trying to get around opening the new window which didn't work, I want at least share my modified version of your script that uses GM_setValue and GM_getValue instead of the cookie hack, which is better in my opinion because it doesn't send the data to the server whenever you reload the site.
Code:
// ==UserScript==
// @name Cubecraft Report Thing
// @namespace de.rasmusantons
// @match https://www.cubecraft.net/
// @match https://www.cubecraft.net/forums/
// @match https://reports.cubecraft.net/report?refresh
// @version 0
// @description Adaption of https://www.cubecraft.net/threads/reporting-statistics.195329/
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==

var updateTime = 30; // Time before the report stats try to update again in minutes

function timeConverter(UNIX_timestamp){ // Unix to normal time
    var a = new Date(UNIX_timestamp * 1000);
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    var year = a.getFullYear();
    var month = months[a.getMonth()];
    var date = a.getDate();
    var hour = a.getHours();
    if(hour < 10) {
        hour = "0" + hour;
    }
    var min = a.getMinutes();
    if(min < 10) {
        min = "0" + min;
    }
    var sec = a.getSeconds();
    if(sec < 10) {
        sec = "0" + sec;
    }
    var time = hour + ':' + min + ':' + sec + ', ' + month + ' ' + date;
    return time;
}

function updateStats() {
    if (window.open('https://reports.cubecraft.net/report?refresh', '_blank'))
        setTimeout(function(){ location.reload(); }, 3000);
}

if (window.location.href == 'https://reports.cubecraft.net/report?refresh') {
    GM_setValue('handledReports', document.querySelector('span.handled').innerHTML);
    GM_setValue('openReports', document.querySelectorAll('span[style="color: #FFA500"]').length);
    GM_setValue('updateTime', new Date().getTime());
    window.close();
} else {
    var openReports = GM_getValue('openReports');
    console.log('reports=' + openReports);
    if(openReports > 9)
        openReports = "10+";
    var handledReports = GM_getValue('handledReports');
    console.log('open=' + openReports + ', handled=' + handledReports);
    if(handledReports) {
        var date = new Date();
        var time = date.getTime();
        document.querySelector('.styliumMainSidebar').innerHTML += '<div class="section widget_ForumStats" id="widget_4">'
            + '<div class="secondaryContent statsList" style="background:#ffffff;">'
            + '<h3>Reporting Statistics</h3><div class="pairsJustified">'
            + '<dl class="discussionCount"><dt>Successful reports:</dt><dd>' + handledReports + '</dd></dl>'
            + '<dl class="messageCount"><dt>Open reports:</dt><dd>' + openReports + '</dd></dl>'
            + '<dl class="mostCount"><dt>Last update:</dt><dd>' + timeConverter(GM_getValue('updateTime')) + '</dd></dl>'
            + '<dl><dd><a href="https://reports.cubecraft.net/report?refresh" target="_blank" onclick="setTimeout(function(){ location.reload(); }, 3000);">Update now</a></dd></dl>'
            + '</div></div></div>';
        var timeDifference = time - GM_getValue('updateTime');
        var updateTimeConv = updateTime * 60 * 1000;
        if(timeDifference > updateTimeConv) {
            updateStats();
        }
        setInterval(function() {
            if(!document.hasFocus()) {
                location.reload();
            }
        }, 300000);
    } else {
        updateStats();
    }
}
Another small thing that I changed: if window.open() returns null because popups are blocked (By default in both Firefox and Chromium for me) it probably shouldn't keep reloading the page over and over.

Edit: I didn't do this, but instead of location.reload() it could just delete and recreate the .widget_ForumStats. That would make using this a lot smoother, it can be a bit irritating if you continue browsing within the 3 seconds and suddenly the page reloads.
 
  • Like
Reactions: DrHam and Max ♠

Max ♠

Forum Expert
Feb 20, 2016
1,420
2,940
344
24
North pole
That is pretty neat.
When looking at the source code I though there must be a less hacky way to do this, something like
Code:
$.ajax({
    type: 'GET',
    url: 'https://reports.cubecraft.net/report',
    xhrFields: {
        withCredentials: true
    }
});
I've never worked with ajax before(I'm relatively new to programming), I did try to use an iframe though. I was able to get the data from the iframe if I put another iframe inside the iframe and retreive the data from the last iframe (I have no clue why I couldn't get it from the 1st).

So after trying to get around opening the new window which didn't work, I want at least share my modified version of your script that uses GM_setValue and GM_getValue instead of the cookie hack, which is better in my opinion because it doesn't send the data to the server whenever you reload the site.
I didn't know about GM_setValue and GM_getValue, are these values stored per file or shared between? (Assuming it's shared as they'd have no advantage over variables otherwise as far as I can guess)

Also,
Code:
if(openReports > 9)
        openReports = "10+";
The reason I had this as 9+ instead of 10+ was for when someone has 10 open reports, it wouldn't make a huge difference but it'd be enough to annoy me :p
Another small thing that I changed: if window.open() returns null because popups are blocked (By default in both Firefox and Chromium for me) it probably shouldn't keep reloading the page over and over.
I'll update my code to do the same in little while, I noticed how it got blocked 1st time testing, completely forgot about it afterwards

I didn't do this, but instead of location.reload() it could just delete and recreate the .widget_ForumStats. That would make using this a lot smoother, it can be a bit irritating if you continue browsing within the 3 seconds and suddenly the page reloads.
I'll look into this when I update the code for the window.open(), I'm assuming it's not as easy as replacing it with document.getElementById('').reload();?

Thanks for the input :]
 

MagnificentSpam

Forum Expert
Mar 16, 2016
2,306
2,238
298
I didn't know about GM_setValue and GM_getValue, are these values stored per file or shared between? (Assuming it's shared as they'd have no advantage over variables otherwise as far as I can guess)
They are defined per script, but they are persistent even if the script is reloaded or loaded on different sites. I think it uses sqlite internally.
The reason I had this as 9+ instead of 10+ was for when someone has 10 open reports, it wouldn't make a huge difference but it'd be enough to annoy me :p
I read 9+ as "9 or more" so I thought it should be "10 or more". Depends on how you read it I guess.
I'll look into this when I update the code for the window.open(), I'm assuming it's not as easy as replacing it with document.getElementById('').reload();?
I changed it in the version I posted, for some reason jquery refused to work now until I put it in a @require, not sure if it's loaded twice now o_O:
Code:
// ==UserScript==
// @name Cubecraft Report Thing
// @namespace de.rasmusantons
// @require https://www.cubecraft.net/js/jquery/jquery-1.11.0.min.js
// @match https://www.cubecraft.net/
// @match https://www.cubecraft.net/forums/
// @match https://reports.cubecraft.net/report?refresh
// @version 0
// @description Adaption of https://www.cubecraft.net/threads/reporting-statistics.195329/
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==

var UPDATE_INTERVAL = 30; // Time before the report stats try to update again in minutes

function timeConverter(UNIX_timestamp){ // Unix to normal time
    var a = new Date(UNIX_timestamp);
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    var month = months[a.getMonth()];
    var date = a.getDate();
    var hour = a.getHours();
    if(hour < 10)
        hour = "0" + hour;
    var min = a.getMinutes();
    if(min < 10)
        min = "0" + min;
    var sec = a.getSeconds();
    if(sec < 10)
        sec = "0" + sec;
    return hour + ':' + min + ':' + sec + ', ' + month + ' ' + date;
}

function drawWidget() {
    document.querySelectorAll('.widget_ReportStats').forEach(function(e) {e.remove()});
    var openReports = GM_getValue('openReports');
    if(openReports > 9)
        openReports = "10+";
    $('.styliumMainSidebar').append('<div class="section widget_ForumStats widget_ReportStats" id="widget_4">'
            + '<div class="secondaryContent statsList" style="background:#ffffff;">'
            + '<h3>Reporting Statistics</h3><div class="pairsJustified">'
            + '<dl class="discussionCount"><dt>Successful reports:</dt><dd>' + GM_getValue('handledReports') + '</dd></dl>'
            + '<dl class="messageCount"><dt>Open reports:</dt><dd>' + openReports + '</dd></dl>'
            + '<dl class="mostCount"><dt>Last update:</dt><dd>' + timeConverter(GM_getValue('updateTime')) + '</dd></dl>'
            + '<dl><dd><a id="updateStatsLink">Update now</a></dd></dl>'
            + '</div></div></div>');
    $('#updateStatsLink').click(updateStats);
}

function updateStats() {
    var popup = window.open('https://reports.cubecraft.net/report?refresh', '_blank', 'width=1,height=1');
    if (popup) {
        var popupWatcher = setInterval(function() {
            if (popup.closed) {
                clearInterval(popupWatcher);
                if (GM_getValue('handledReports') !== undefined)
                    drawWidget();
            }
        }, 100);
    }
}

$(document).ready(function() {
    if (window.location.href == 'https://reports.cubecraft.net/report?refresh') {
        GM_setValue('handledReports', document.querySelector('span.handled').innerHTML);
        GM_setValue('openReports', document.querySelectorAll('span[style="color: #FFA500"]').length);
        GM_setValue('updateTime', new Date().getTime());
        window.close();
    } else {
        if (GM_getValue('handledReports') !== undefined) {
            drawWidget();
            if (new Date().getTime() - GM_getValue('updateTime') > UPDATE_INTERVAL * 60 * 1000)
                updateStats();
        } else {
            updateStats();
        }
        setInterval(function() {
            updateStats();
        }, UPDATE_INTERVAL * 60 * 1000);
    }
});
I also made it open the report site in a new window instead of a new tab, not sure how that behaves on windows though.
 
Last edited:

Max ♠

Forum Expert
Feb 20, 2016
1,420
2,940
344
24
North pole
They are defined per script, but they are persistent even if the script is reloaded or loaded on different sites. I think it uses sqlite internally.

I read 9+ as "9 or more" so I thought it should be "10 or more". Depends on how you read it I guess.

I changed it in the version I posted, for some reason jquery refused to work now until I put it in a @require, not sure if it's loaded twice now o_O:
Code:
// ==UserScript==
// @name Cubecraft Report Thing
// @namespace de.rasmusantons
// @require https://www.cubecraft.net/js/jquery/jquery-1.11.0.min.js
// @match https://www.cubecraft.net/
// @match https://www.cubecraft.net/forums/
// @match https://reports.cubecraft.net/report?refresh
// @version 0
// @description Adaption of https://www.cubecraft.net/threads/reporting-statistics.195329/
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==

var UPDATE_INTERVAL = 30; // Time before the report stats try to update again in minutes

function timeConverter(UNIX_timestamp){ // Unix to normal time
    var a = new Date(UNIX_timestamp);
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    var month = months[a.getMonth()];
    var date = a.getDate();
    var hour = a.getHours();
    if(hour < 10)
        hour = "0" + hour;
    var min = a.getMinutes();
    if(min < 10)
        min = "0" + min;
    var sec = a.getSeconds();
    if(sec < 10)
        sec = "0" + sec;
    return hour + ':' + min + ':' + sec + ', ' + month + ' ' + date;
}

function drawWidget() {
    document.querySelectorAll('.widget_ReportStats').forEach(function(e) {e.remove()});
    var openReports = GM_getValue('openReports');
    if(openReports > 9)
        openReports = "10+";
    $('.styliumMainSidebar').append('<div class="section widget_ForumStats widget_ReportStats" id="widget_4">'
            + '<div class="secondaryContent statsList" style="background:#ffffff;">'
            + '<h3>Reporting Statistics</h3><div class="pairsJustified">'
            + '<dl class="discussionCount"><dt>Successful reports:</dt><dd>' + GM_getValue('handledReports') + '</dd></dl>'
            + '<dl class="messageCount"><dt>Open reports:</dt><dd>' + openReports + '</dd></dl>'
            + '<dl class="mostCount"><dt>Last update:</dt><dd>' + timeConverter(GM_getValue('updateTime')) + '</dd></dl>'
            + '<dl><dd><a id="updateStatsLink">Update now</a></dd></dl>'
            + '</div></div></div>');
    $('#updateStatsLink').click(updateStats);
}

function updateStats() {
    var popup = window.open('https://reports.cubecraft.net/report?refresh', '_blank', 'width=1,height=1');
    if (popup) {
        var popupWatcher = setInterval(function() {
            if (popup.closed) {
                clearInterval(popupWatcher);
                if (GM_getValue('handledReports') !== undefined)
                    drawWidget();
            }
        }, 100);
    }
}

$(document).ready(function() {
    if (window.location.href == 'https://reports.cubecraft.net/report?refresh') {
        GM_setValue('handledReports', document.querySelector('span.handled').innerHTML);
        GM_setValue('openReports', document.querySelectorAll('span[style="color: #FFA500"]').length);
        GM_setValue('updateTime', new Date().getTime());
        window.close();
    } else {
        if (GM_getValue('handledReports') !== undefined) {
            drawWidget();
            if (new Date().getTime() - GM_getValue('updateTime') > UPDATE_INTERVAL * 60 * 1000)
                updateStats();
        } else {
            updateStats();
        }
        setInterval(function() {
            updateStats();
        }, UPDATE_INTERVAL * 60 * 1000);
    }
});
I also made it open the report site in a new window instead of a new tab, not sure how that behaves on windows though.

Doesn't seem to be working for me, I tried using Opera with ViolentMonkey (there's no greasemonkey for Opera, I expected it not to work due to the GM_setValue), same for Chrome. It did work using Firefox & GreaseMonkey though, is it okay for me to include this in the original post as a firefox option?
 

MagnificentSpam

Forum Expert
Mar 16, 2016
2,306
2,238
298
Doesn't seem to be working for me, I tried using Opera with ViolentMonkey (there's no greasemonkey for Opera, I expected it not to work due to the GM_setValue), same for Chrome. It did work using Firefox & GreaseMonkey though, is it okay for me to include this in the original post as a firefox option?
It should work in chrome, if it doesn't, I probably broke something else. Opera really doesn't have that feature. You can use my edited version of the script in any way.

Edit: It works on Chromium for me, but I also just found this: https://wiki.greasespot.net/GM_xmlhttpRequest
That might remove the need to open a new window. I am not sure if it will send the original cookies of the report site so you're logged in there.
 
Last edited:
  • Like
Reactions: Max ♠
Status
Not open for further replies.
Members Online

Team online

Latest profile posts

TheOrderOfSapphire wrote on Otherworld's profile.
💙
UncleSpect wrote on Fly☆Guy's profile.
Happy birthday!
TheOrderOfSapphire wrote on Fly☆Guy's profile.
Happy Birthday my friend, I hope you have a wonderful day today!:D
GiGaGekkies wrote on Fly☆Guy's profile.
Happy Birthday!
GiGaGekkies wrote on Migratie's profile.
Happy Birthday
Top Bottom