Skip to content

Instantly share code, notes, and snippets.

@leemars
Last active August 29, 2015 14:14
Show Gist options
  • Save leemars/abacb7726d00101b6c24 to your computer and use it in GitHub Desktop.
Save leemars/abacb7726d00101b6c24 to your computer and use it in GitHub Desktop.
Skywatcher marker
// ==UserScript==
// @name Skywatcher Marker
// @namespace http://your.homepage/
// @version 0.2.3
// @description enter something useful
// @author You
// @match http://ff14.com.cn/wiki/%E6%8E%A2%E9%99%A9%E7%AC%94%E8%AE%B0*
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// ==/UserScript==
// allows using all Jquery AJAX methods in Greasemonkey
// inspired from http://ryangreenberg.com/archives/2010/03/greasemonkey_jquery.php
// works with JQuery 1.5
// (c) 2011 Martin Monperrus
// (c) 2010 Ryan Greenberg
//
// Usage:
// $.ajax({
// url: '/p/',
// xhr: function(){return new GM_XHR();},
// type: 'POST',
// success: function(val){
// ....
// }
// });
function GM_XHR() {
this.type = null;
this.url = null;
this.async = null;
this.username = null;
this.password = null;
this.status = null;
this.headers = {};
this.readyState = null;
this.abort = function() {
this.readyState = 0;
};
this.getAllResponseHeaders = function(name) {
if (this.readyState!=4) return "";
return this.responseHeaders;
};
this.getResponseHeader = function(name) {
var regexp = new RegExp('^'+name+': (.*)$','im');
var match = regexp.exec(this.responseHeaders);
if (match) { return match[1]; }
return '';
};
this.open = function(type, url, async, username, password) {
this.type = type ? type : null;
this.url = url ? url : null;
this.async = async ? async : null;
this.username = username ? username : null;
this.password = password ? password : null;
this.readyState = 1;
};
this.setRequestHeader = function(name, value) {
this.headers[name] = value;
};
this.send = function(data) {
this.data = data;
var that = this;
// http://wiki.greasespot.net/GM_xmlhttpRequest
GM_xmlhttpRequest({
method: this.type,
url: this.url,
headers: this.headers,
data: this.data,
onload: function(rsp) {
// Populate wrapper object with returned data
// including the Greasemonkey specific "responseHeaders"
for (var k in rsp) {
that[k] = rsp[k];
}
// now we call onreadystatechange
that.onreadystatechange();
},
onerror: function(rsp) {
for (var k in rsp) {
that[k] = rsp[k];
}
}
});
};
}
var AREAS = ["", "リムサ·ロミンサ", "中央ラノシア", "低地ラノシア", "東ラノシア", "西ラノシア", "高地ラノシア", "外地ラノシア", "ウルヴズジェイル係船場", "ミスト・ヴィレッジ", "グリダニア", "黒衣森:中央森林", "黒衣森:東部森林", "黒衣森:南部森林", "黒衣森:北部森林", "ラベンダーベッド", "ウルダハ", "西ザナラーン", "中央ザナラーン", "東ザナラーン", "南ザナラーン", "北ザナラーン", "ゴブレットビュート", "クルザス中央高地", "モードゥナ"];
var WEATHERS = ["", "快晴", "晴れ", "曇り", "霧", "風", "暴風", "雨", "暴雨", "雷", "雷雨", "砂塵", "砂嵐", "熱波", "灼熱波", "雪", "吹雪", "オーロラ", "妖霧"];
var getSimilarWeather = function(weather) {
switch(weather) {
case "快晴":
case "晴れ":
return "快晴";
case "風":
case "暴風":
return "風";
case "雨":
case "暴雨":
return "雨";
case "雷":
case "雷雨":
return "雷";
case "砂塵":
case "砂嵐":
return "砂塵";
case "熱波":
case "灼熱波":
return "熱波";
case "雪":
case "吹雪":
return "雪";
default:
return weather;
}
};
var skywatcher;
var buildSkywatcher = function(data) {
skywatcher = {};
$.each(data, function(i, e) {
var aid = parseInt(e.area, 10);
var area = AREAS[aid];
var wid = parseInt(e.weather, 10);
var weather = WEATHERS[wid];
var time = e.time;
if (skywatcher[area] === undefined) {
skywatcher[area] = {};
}
skywatcher[area][time] = weather;
});
};
var getSightseeingArea = function(tr) {
var pos = $('td:nth(2)', tr).html();
if (!pos) {
return pos;
}
var area = pos.split('<br>')[0].trim();
for (var i = 1; i < AREAS.length; ++i) {
if (area.indexOf(AREAS[i]) === 0) {
return AREAS[i];
}
}
};
var getSightseeingWeather = function(tr) {
var weather = $('td:nth(4)', tr).text();
if (!weather) {
return weather;
}
weather = weather.split('/')[0].trim();
return weather;
};
var getSightseeingTime = function(tr) {
var time = $('td:nth(3)', tr).text();
if (!time) {
return time;
}
time = time.split('~');
var start_time = time[0].trim();
var end_time = time[1].trim();
return [start_time, end_time];
};
var getCurrentTime = function() {
var time = $('#ETime').text();
if (!time) {
return time;
}
time = time.split('/')[1].trim();
if (time.length === 4) {
time = '0' + time;
}
return time;
};
var isSimilarWeather = function(w1, w2) {
return getSimilarWeather(w1) === getSimilarWeather(w2);
};
var isInTimeInterval = function(t, ti) {
if (ti[0] <= ti[1]) {
return ti[0] <= t && t <= ti[1];
} else {
return (ti[0] <= t && t <= '23:59') || ('00:00' <= t && t <= ti[1]);
}
};
var markTableRow = function(tr) {
var area = getSightseeingArea(tr);
if (!area) {
return;
}
var time_interval = getSightseeingTime(tr);
if (!time_interval) {
return;
}
var current_time = getCurrentTime();
if (!current_time) {
return;
}
var weather = getSightseeingWeather(tr);
if (!weather) {
return;
}
var weather_area = skywatcher[area];
if (!weather_area) {
return;
}
var weather_now = weather_area[0];
if (!weather_now) {
return;
}
var weather_hint = $('<p></p>').addClass('weather-now').text(weather_now);
$('td:nth(7)', tr).append(weather_hint);
if (isSimilarWeather(weather, weather_now) &&
isInTimeInterval(current_time, time_interval)) {
$(tr).addClass('sightseeing-available');
} else {
$(tr).removeClass('sightseeing-available');
}
};
var markTables = function() {
$('.weather-now').remove();
$('.wikitable tr').each(function(i, e) {
markTableRow(e);
});
setTimeout(main, 60*1000);
};
var main = function() {
$.ajax({
url: 'http://jp.ff14angler.com/skywatcher.php?name=1',
xhr: function() { return new GM_XHR(); },
success: function(response) {
console.log(getCurrentTime());
buildSkywatcher(response.data);
markTables();
}
});
};
$(function() {
GM_addStyle('.sightseeing-available { background: #e7e7e7 !important; }');
setTimeout(main, 5000);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment