• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

2005~2007年頃に存在したYggdrasil-System (SNS) にfb2k上の曲再生情報を投稿するためのYamabikoClient互換プラグイン、および、派生版のmixi station互換プラグインのソース。


Commit MetaInfo

Revisión6d5d0c08eb970e808f2c3554e179ea289825ba06 (tree)
Tiempo2016-10-30 14:51:20
Autoryoshy <yoshy@user...>
Commiteryoshy

Log Message

[ADD] foo_yggd, foo_mixi

Cambiar Resumen

Diferencia incremental

--- /dev/null
+++ b/foo_mixi/foo_mixi.cpp
@@ -0,0 +1,958 @@
1+#include <windows.h>
2+#include <lmcons.h>
3+#include <process.h>
4+#include <mmsystem.h>
5+#include <vector>
6+#include <memory>
7+#include "../SDK/foobar2000.h"
8+#include "../helpers/helpers.h"
9+#include "wx/protocol/http.h"
10+#include "wx/url.h"
11+#include "wx/sstream.h"
12+#include "wx/tokenzr.h"
13+#include "wx/datetime.h"
14+#include "resource.h"
15+
16+/*
17+ foo_mixi: project dependencies
18+
19+ foo_mixi
20+ foobar2000_SDK
21+ utf8api
22+ pfc
23+ foobar2000_sdk_helpers
24+ pfc
25+
26+ library dependencies: wxbase26_net.lib wxbase26.lib wsock32.lib
27+ used runtime library: Multi-Thread (DLL) (ensure all dependenced projects)
28+ ignored library: LIBCMT
29+*/
30+
31+#pragma comment(lib, "wxbase26_net.lib")
32+#pragma comment(lib, "wxbase26.lib")
33+#pragma comment(lib, "wsock32.lib")
34+
35+#define PLUGIN_CAPTION "YamabikoClient plugin"
36+#define PLUGIN_CAPTION2 " for mixi"
37+#define PLUGIN_CAPTION3 " (mixi)"
38+#define PLUGIN_VERSION "0.0.0.4"
39+
40+typedef char Str64K[65536];
41+
42+void DebugPrint(LPCSTR lpszFormat, ...);
43+
44+#define ENABLE_DEBUG true
45+#define ENABLE_DEBUG_TRACKINFO false
46+#define ENABLE_DEBUG_TRACKINFO_SHOW true
47+#define ENABLE_DEBUG_PLUGIN true
48+#define ENABLE_DEBUG_MIXI true
49+#define ENABLE_DEBUG_MIXI_ACCOUNT false
50+#define ENABLE_DEBUG_MIXI_ENCODE false
51+
52+#define TRACE(x) if(ENABLE_DEBUG) { OutputDebugString(x); OutputDebugString("\n"); console::info(x); }
53+#define TRACE_SJIS(x) if(ENABLE_DEBUG) { string_utf8_from_ansi tmp(x); OutputDebugString(x); OutputDebugString("\n"); console::info(tmp); }
54+
55+#define TRACE_TRACKINFO(x) if(ENABLE_DEBUG_TRACKINFO) TRACE(x)
56+#define TRACE_TRACKINFO_SHOW_SJIS(x) if(ENABLE_DEBUG_TRACKINFO_SHOW) TRACE_SJIS(x)
57+
58+#define TRACE_PLUGIN(x) if(ENABLE_DEBUG_PLUGIN) TRACE(x)
59+#define TRACE_PLUGIN_SJIS(x) if(ENABLE_DEBUG_PLUGIN) TRACE_SJIS(x)
60+
61+#define TRACE_MIXI(x) if(ENABLE_DEBUG_MIXI) TRACE(x)
62+#define TRACE_MIXI_SJIS(x) if(ENABLE_DEBUG_MIXI) TRACE_SJIS(x)
63+
64+#define TRACE_MIXI_ACCOUNT(x) if(ENABLE_DEBUG_MIXI_ENCODE) TRACE(x)
65+
66+#define TRACE_MIXI_ENCODE(x) if(ENABLE_DEBUG_MIXI_ENCODE) TRACE(x)
67+#define TRACE_MIXI_ENCODE_SJIS(x) if(ENABLE_DEBUG_MIXI_ENCODE) TRACE_SJIS(x)
68+
69+DECLARE_COMPONENT_VERSION(PLUGIN_CAPTION PLUGIN_CAPTION2, PLUGIN_VERSION, PLUGIN_CAPTION PLUGIN_CAPTION3);
70+
71+static cfg_int cfg_enabled("enabled",1);
72+
73+static cfg_string cfg_username("UserName","");
74+static cfg_string cfg_password("PassWord","");
75+
76+static cfg_string cfg_yamabiko_interval1("YamabikoInterval1","20");
77+static cfg_string cfg_yamabiko_interval2("YamabikoInterval2","66");
78+
79+static cfg_int cfg_proxy_enabled("useProxy",0);
80+static cfg_string cfg_proxy_server("ProxyServer","");
81+static cfg_string cfg_proxy_port("ProxyPort","");
82+
83+struct TRACK_INFO
84+{
85+ bool m_isEmpty;
86+ wxString m_title;
87+ wxString m_album;
88+ wxString m_artist;
89+ wxString m_genre;
90+
91+ TRACK_INFO() : m_isEmpty(true) {}
92+
93+ void set(LPCSTR title, LPCSTR album, LPCSTR artist, LPCSTR genre)
94+ {
95+ TRACE_TRACKINFO("TRACK_INFO::set - called.");
96+
97+ if(title) m_title = title; else m_title.Clear();
98+ if(album) m_album = album; else m_album.Clear();
99+ if(artist) m_artist = artist; else m_artist.Clear();
100+ if(genre) m_genre = genre; else m_genre.Clear();
101+
102+ m_isEmpty = false;
103+ }
104+
105+ void clear()
106+ {
107+ TRACE_TRACKINFO("TRACK_INFO::clear - called.");
108+
109+ m_title.Clear();
110+ m_album.Clear();
111+ m_artist.Clear();
112+ m_genre.Clear();
113+
114+ m_isEmpty = true;
115+ }
116+
117+ void show() const
118+ {
119+ if(!m_title.IsEmpty()) { TRACE_TRACKINFO_SHOW_SJIS(m_title); } else { TRACE_TRACKINFO("title null."); }
120+ if(!m_album.IsEmpty()) { TRACE_TRACKINFO_SHOW_SJIS(m_album); } else { TRACE_TRACKINFO("album null."); }
121+ if(!m_artist.IsEmpty()) { TRACE_TRACKINFO_SHOW_SJIS(m_artist); } else { TRACE_TRACKINFO("artist null."); }
122+ if(!m_genre.IsEmpty()) { TRACE_TRACKINFO_SHOW_SJIS(m_genre); } else { TRACE_TRACKINFO("genre null."); }
123+ }
124+
125+ bool isEmpty() const { return m_isEmpty; }
126+};
127+
128+class mixi
129+{
130+public:
131+
132+ void setAccountInfo(LPCSTR user, LPCSTR pass)
133+ {
134+ TRACE_MIXI_ACCOUNT("mixi::setAccountInfo - called.");
135+ TRACE_MIXI_ACCOUNT(user);
136+ TRACE_MIXI_ACCOUNT(pass);
137+
138+ m_username = encodeURL(user);
139+ m_password = encodeURL(pass);
140+// m_username = user;
141+// m_password = pass;
142+ }
143+
144+ bool postYamabiko(const TRACK_INFO &info)
145+ {
146+ TRACE_MIXI("mixi::postYamabiko - enter.");
147+
148+ if(m_sessionid.IsEmpty())
149+ {
150+ if(!login())
151+ {
152+ TRACE_MIXI("mixi::postYamabiko - first login failed.");
153+ return false;
154+ }
155+ }
156+
157+ wxString yamabiko;
158+ yamabiko = createYamabiko(info);
159+
160+ if(!do_post("/music/upload.pl", yamabiko))
161+ {
162+ if(!login())
163+ {
164+ TRACE_MIXI("mixi::postYamabiko - relogin failed.");
165+ return false;
166+ }
167+
168+ yamabiko = createYamabiko(info);
169+
170+ if(!do_post("/upload.pl", yamabiko))
171+ {
172+ TRACE_MIXI("mixi::postYamabiko - post yamabiko failed after logged in.");
173+ return false;
174+ }
175+ else
176+ {
177+ TRACE_MIXI("mixi::postYamabiko - yamabiko posted successfully after logged in.");
178+ }
179+ }
180+ else
181+ {
182+ TRACE_MIXI("mixi::postYamabiko - yamabiko posted successfully.");
183+ }
184+
185+ TRACE_MIXI("mixi::postYamabiko - exit.");
186+
187+ return true;
188+ }
189+
190+ bool postYamabikoToMixiClient(const TRACK_INFO &info)
191+ {
192+ TRACE_MIXI(_T("mixi::postYamabikoToMixiClient - enter."));
193+
194+ wxString yamabiko;
195+ yamabiko = createYamabikoForMixiClient(info);
196+
197+ bool bResult = writeMailSlot(yamabiko);
198+
199+ TRACE_MIXI(_T("mixi::postYamabikoToMixiClient - exit."));
200+
201+ return bResult;
202+ }
203+
204+ bool login()
205+ {
206+ TRACE_MIXI("mixi::login - enter.");
207+
208+ wxString postBuf(
209+ wxString::Format(
210+ "email=%s&password=%s",
211+ (LPCSTR)m_username, (LPCSTR)m_password
212+ )
213+ );
214+
215+ if(!do_post("/music/login.pl", postBuf, true))
216+ {
217+ TRACE_MIXI("mixi::login - post method failed.");
218+ return false;
219+ }
220+
221+ if(m_status == "OK")
222+ {
223+ TRACE_MIXI("mixi::login - got session id successfully");
224+ }
225+ else
226+ {
227+ TRACE_MIXI("mixi::login - login failed.");
228+ return false;
229+ }
230+
231+ TRACE_MIXI("mixi::login - successfully logged in.");
232+
233+ return true;
234+ }
235+
236+protected:
237+
238+ bool writeMailSlot(const wxString &yamabiko)
239+ {
240+ TRACE_MIXI(_T("mixi::writeMailSlot - enter."));
241+
242+ HANDLE hFile;
243+ BOOL bResult;
244+ DWORD dwWritten;
245+
246+ wxString mailSlot(wxT("\\\\.\\mailslot\\jp.mixi.mmm\\report_song\\"));
247+ wxString logonUserName;
248+ DWORD dwUNLen = UNLEN;
249+
250+ if(::GetUserName(logonUserName.GetWriteBuf(UNLEN), &dwUNLen) == FALSE)
251+ {
252+ TRACE_MIXI(_T("mixi::writeMailSlot - get logon username failed."));
253+ return false;
254+ }
255+
256+ logonUserName.UngetWriteBuf();
257+ DebugPrint(_T("mixi::writeMailSlot - logon user: %s"), (LPCTSTR)logonUserName);
258+
259+ mailSlot += logonUserName;
260+ DebugPrint(_T("mixi::writeMailSlot - mail slot: %s"), (LPCTSTR)mailSlot);
261+
262+ hFile = CreateFile(
263+ mailSlot, GENERIC_WRITE,
264+ FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
265+ NULL
266+ );
267+
268+ if (hFile == INVALID_HANDLE_VALUE) {
269+ TRACE_MIXI(_T("mixi::writeMailSlot - MixiClient not ready."));
270+ return false;
271+ }
272+
273+ DebugPrint(_T("mixi::writeMailSlot - report: %s"), (LPCTSTR)yamabiko);
274+
275+ //string_utf8_from_wide wideForm(yamabiko);
276+ string_utf8_from_ansi wideForm(yamabiko);
277+
278+ bResult = WriteFile(hFile, (LPCSTR)wideForm, (int)strlen((LPCSTR)wideForm) + 1, &dwWritten, NULL);
279+
280+ if (bResult == FALSE) {
281+ TRACE_MIXI(_T("mixi::writeMailSlot - send mailslot failed."));
282+ CloseHandle(hFile);
283+ return false;
284+ }
285+
286+ CloseHandle(hFile);
287+
288+ TRACE_MIXI(_T("mixi::writeMailSlot - exit."));
289+
290+ return true;
291+ }
292+
293+ bool do_post(LPCSTR path, LPCSTR postBuf, bool isLogin = false)
294+ {
295+ TRACE_MIXI("mixi::do_post - enter.");
296+
297+ wxString host("http://upload.mixi.jp");
298+ host += path;
299+ wxURL url(host);
300+
301+ if(cfg_proxy_enabled == 1)
302+ {
303+ wxString proxyURL(cfg_proxy_server);
304+ wxString proxyPort(cfg_proxy_port);
305+ if(proxyPort.Length() > 0)
306+ {
307+ proxyURL += ":";
308+ proxyURL += proxyPort;
309+ }
310+ url.SetProxy(proxyURL);
311+ TRACE_MIXI(proxyURL);
312+ }
313+
314+ wxHTTP &http = static_cast<wxHTTP &>(url.GetProtocol());
315+
316+ http.SetHeader("Content-Type", "application/x-www-form-urlencoded");
317+
318+ http.SetPostBuffer(postBuf);
319+
320+ TRACE_MIXI( path );
321+ TRACE_MIXI( postBuf );
322+
323+ std::auto_ptr<wxInputStream> in( url.GetInputStream() );
324+ std::auto_ptr<wxStringOutputStream> out( new wxStringOutputStream() );
325+
326+ m_response = http.GetResponse();
327+ bool res = false;
328+
329+ if(m_response == 200)
330+ {
331+ TRACE_MIXI("mixi::do_post - 200 post succeeded.");
332+
333+ in->Read(*out);
334+ m_body = out->GetString();
335+ parseResponse();
336+
337+ TRACE_MIXI_SJIS( m_body );
338+
339+ if(m_status == "OK")
340+ {
341+ TRACE_MIXI("mixi::do_post - status ok");
342+ res = true;
343+ }
344+ else
345+ {
346+ TRACE_MIXI("mixi::do_post - status " + m_status);
347+ }
348+
349+ }
350+ else
351+ {
352+ m_body.Clear();
353+ wxString responseStr;
354+ responseStr.Format("%d", m_response);
355+ TRACE_MIXI("mixi::do_post - " + responseStr + " post failed.");
356+ }
357+
358+ TRACE_MIXI("mixi::do_post - exit");
359+ return res;
360+ }
361+
362+ void parseResponse() {
363+
364+ wxStringTokenizer lineTkz(m_body);
365+ while ( lineTkz.HasMoreTokens() )
366+ {
367+ wxString line = lineTkz.GetNextToken();
368+
369+ wxStringTokenizer wordTkz(line, wxT("="));
370+
371+ boolean keyFlg = false;
372+ boolean valFlg = false;
373+ int keyKind = -1;
374+ wxString word;
375+
376+ while ( wordTkz.HasMoreTokens() )
377+ {
378+ word = wordTkz.GetNextToken();
379+
380+ if(keyFlg == false)
381+ {
382+ if(word == "status")
383+ {
384+ keyKind = 0;
385+ }
386+ else if(word == "session_id")
387+ {
388+ keyKind = 1;
389+ }
390+ else if(word == "url")
391+ {
392+ keyKind = 2;
393+ }
394+
395+ keyFlg = true;
396+ }
397+ else
398+ {
399+ valFlg = true;
400+ }
401+ }
402+
403+ if(keyFlg && valFlg)
404+ {
405+ switch(keyKind)
406+ {
407+ case 0:
408+ m_status = word;
409+ break;
410+ case 1:
411+ m_sessionid = word;
412+ break;
413+ case 2:
414+ m_url = word;
415+ break;
416+ default:
417+ break;
418+ }
419+ }
420+ }
421+ }
422+
423+ wxString createYamabiko(const TRACK_INFO &info)
424+ {
425+ TRACK_INFO encodedInfo;
426+
427+ info.show();
428+
429+ encodedInfo.set(
430+ encodeURL(info.m_title),
431+ encodeURL(info.m_album),
432+ encodeURL(info.m_artist),
433+ encodeURL(info.m_genre)
434+ );
435+
436+ wxString path(
437+ wxString::Format(
438+ "session_id=%s&data=<?xml version=\"1.0\" encoding=\"UTF-8\"?>%%0d%%0a<report>%%0d%%0a<stream>%%0d%%0a<title>%s</title>%%0d%%0a<url>dummy</url>%%0d%%0a<artist>%s</artist>%%0d%%0a<album>%s</album>%%0d%%0a<genre>%s</genre>%%0d%%0a<timestamp>%s</timestamp>%%0d%%0a</stream>%%0d%%0a</report>",
439+ m_sessionid, encodedInfo.m_title, encodedInfo.m_artist, encodedInfo.m_album, encodedInfo.m_genre, getTimeStamp()
440+ )
441+ );
442+
443+ return path;
444+ }
445+
446+ wxString createYamabikoForMixiClient(const TRACK_INFO &info)
447+ {
448+ TRACK_INFO encodedInfo;
449+
450+ info.show();
451+
452+ wxString path(
453+ wxString::Format(
454+ wxT("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
455+ wxT("<reports>\n<report type=\"song\">\n<param key=\"song_title\">%s</param>\n")
456+ wxT("<param key=\"song_artist\">%s</param>\n<param key=\"song_album\">%s</param>\n")
457+ wxT("<param key=\"song_genre\">%s</param>\n</report>\n</reports>"),
458+ info.m_title, info.m_artist, info.m_album, info.m_genre
459+ )
460+ );
461+
462+ return path;
463+ }
464+
465+ wxString encodeURL(LPCSTR srcStr)
466+ {
467+ wxString temp(srcStr);
468+ return encodeURL(temp);
469+ }
470+
471+ wxString encodeURL(const wxString &srcStr)
472+ {
473+ TRACE_MIXI_ENCODE("TRACK_INFO::encodeURL - enter.");
474+ TRACE_MIXI_ENCODE_SJIS(srcStr);
475+
476+ size_t srcStrLen = srcStr.Length();
477+ //DebugPrint("length - %d", srcStrLen);
478+
479+ wxString dstStr;
480+ char *dstPtr = dstStr.GetWriteBuf(srcStrLen * 3 + 1);
481+
482+ for(const char *srcPtr = srcStr; *srcPtr != '\0'; srcPtr ++)
483+ {
484+ unsigned char c = *srcPtr;
485+
486+ if(
487+ ((c >= 'a') && (c <= 'z')) ||
488+ ((c >= 'A') && (c <= 'Z')) ||
489+ ((c >= '0') && (c <= '9')) ||
490+ (strchr("-_.!~*'()", c) != NULL)
491+ ){
492+ *dstPtr ++ = c;
493+ }
494+ else
495+ {
496+ *dstPtr ++ = '%';
497+ *dstPtr ++ = hex(c >> 4);
498+ *dstPtr ++ = hex(c & 0x0f);
499+ }
500+ }
501+
502+ *dstPtr = '\0';
503+ dstStr.UngetWriteBuf();
504+
505+ TRACE_MIXI_ENCODE(dstStr);
506+ TRACE_MIXI_ENCODE("TRACK_INFO::encode - exit.");
507+
508+ return dstStr;
509+ }
510+
511+ static wxString getTimeStamp() {
512+
513+ wxDateTime dateTime;
514+ dateTime.SetToCurrent();
515+
516+ wxString date = dateTime.FormatISODate();
517+ wxString time = dateTime.FormatISOTime();
518+
519+ return date + "T" + time + "%2b09:00";
520+ }
521+
522+ char hex(char val)
523+ {
524+ return (val < 10) ? '0' + val : 'a' + (val - 10);
525+ }
526+
527+ int m_response; //!< http response code
528+ wxString m_username; //!< user account name
529+ wxString m_password; //!< password
530+ wxString m_body; //!< http response body
531+ wxString m_sessionid; //!< session id from server response body
532+ wxString m_status; //!< status from server response body
533+ wxString m_url; //!< url from server response body
534+};
535+
536+class play_callback_yamabiko : public play_callback
537+{
538+ TRACK_INFO m_previous_track;
539+ mixi m_mixi;
540+ double m_previous_sec;
541+ double m_song_total_sec;
542+ bool m_sendEnable;
543+ bool m_sendOnce;
544+
545+ virtual void on_playback_starting()
546+ {
547+ if(!cfg_enabled) return;
548+
549+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_starting called.");
550+
551+ // do something
552+ }
553+
554+ virtual void on_playback_new_track(metadb_handle * track)
555+ {
556+ if(!cfg_enabled) return;
557+
558+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_new_track called.");
559+
560+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_new_track - post previous track informations ...");
561+
562+ // sending track informations
563+ do_post(m_previous_track);
564+ m_previous_track.clear();
565+
566+ // reset send timing
567+ resetSendTiming();
568+
569+ // get currently playbacked track informations
570+ string8 title_utf8;
571+ string8 album_utf8;
572+ string8 artist_utf8;
573+ string8 genre_utf8;
574+
575+ track->handle_format_title(title_utf8, "%title%", 0);
576+ track->handle_format_title(album_utf8, "%album%", 0);
577+ track->handle_format_title(artist_utf8, "%artist%", 0);
578+ track->handle_format_title(genre_utf8, "%genre%", 0);
579+
580+ string_ansi_from_utf8 title(title_utf8);
581+ string_ansi_from_utf8 album(album_utf8);
582+ string_ansi_from_utf8 artist(artist_utf8);
583+ string_ansi_from_utf8 genre(genre_utf8);
584+
585+ m_song_total_sec = track->handle_get_length();
586+
587+ // set current track informations
588+ m_previous_track.set(title, album, artist, genre);
589+ }
590+
591+ virtual void on_playback_stop(play_control::stop_reason reason)
592+ {
593+ if(!cfg_enabled) return;
594+
595+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_stop called.");
596+
597+ // clear current track information
598+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_stop - reset track information.");
599+ m_previous_track.clear();
600+ }
601+
602+ // timeは秒
603+ virtual void on_playback_seek(double time)
604+ {
605+ if(!cfg_enabled) return;
606+
607+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_seek called.");
608+
609+ // clear current track information
610+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_seek - reset track information.");
611+ m_previous_track.clear();
612+ }
613+
614+ virtual void on_playback_pause(int state)
615+ {
616+ if(!cfg_enabled) return;
617+
618+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_pause called.");
619+
620+ // do something
621+ }
622+
623+ virtual void on_playback_edited(metadb_handle * track){}//currently played file got edited
624+
625+ virtual void on_playback_dynamic_info(const file_info * info,bool b_track_change){}
626+
627+ virtual void on_playback_time(metadb_handle * track,double val) //called every second
628+ {
629+ if(!cfg_enabled) return;
630+
631+ if(checkSendTiming(val) == true)
632+ {
633+ if(m_sendEnable == false)
634+ {
635+ m_sendEnable = true;
636+ }
637+ else if(m_sendOnce == false)
638+ {
639+ // force sending track informations
640+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_time - force post track informations ...");
641+ m_sendOnce = true;
642+ do_post(m_previous_track);
643+ m_previous_track.clear();
644+ }
645+ }
646+ }
647+
648+ // virtual void on_volume_change(int new_val) {}//may also happen when not playing
649+
650+ void do_post(const TRACK_INFO &info)
651+ {
652+ TRACE_PLUGIN("play_callback_yamabiko::doPost - enter");
653+
654+ if(m_sendEnable)
655+ {
656+ if(info.isEmpty() == false)
657+ {
658+ m_mixi.setAccountInfo(cfg_username, cfg_password);
659+ if(m_mixi.postYamabikoToMixiClient(info) == false)
660+ {
661+ TRACE_PLUGIN("play_callback_yamabiko::doPost - postYamabiko failed.");
662+ }
663+ }
664+ else
665+ {
666+ TRACE_PLUGIN("play_callback_yamabiko::doPost - track information empty, skip post.");
667+ }
668+ }
669+ else
670+ {
671+ TRACE_PLUGIN("play_callback_yamabiko::doPost - playbacked time too short, skip post.");
672+ }
673+
674+ TRACE_PLUGIN("play_callback_yamabiko::doPost - exit");
675+ }
676+
677+ void resetSendTiming()
678+ {
679+ TRACE_PLUGIN("play_callback_yamabiko::resetSendTiming - called");
680+ m_previous_sec = -1.0;
681+ m_sendEnable = false;
682+ m_sendOnce = false;
683+ }
684+
685+ bool checkSendTiming(double sec)
686+ {
687+ double interval;
688+ double interval1 = pfc_string_to_float(cfg_yamabiko_interval1);
689+ double interval2 = m_song_total_sec * pfc_string_to_float(cfg_yamabiko_interval2) / 100.0;
690+
691+ if(interval2 < interval1) interval2 = interval1;
692+
693+ if(m_sendEnable == false)
694+ {
695+ interval = interval1;
696+ }
697+ else if(m_sendOnce == false)
698+ {
699+ interval = interval2;
700+ }
701+ else
702+ {
703+ return false;
704+ }
705+
706+ if(interval < 10.0) interval = 10.0;
707+
708+ if(m_previous_sec < 0.0)
709+ {
710+ m_previous_sec = sec;
711+ }
712+
713+ if(sec - m_previous_sec > interval)
714+ {
715+ return true;
716+ }
717+
718+ return false;
719+ }
720+};
721+
722+class initquit_yamabiko : public initquit
723+{
724+ virtual void on_init()
725+ {
726+ // do something
727+ }
728+
729+ virtual void on_quit()
730+ {
731+ // do something
732+ }
733+};
734+
735+class menu_item_yamabiko : public menu_item_main
736+{
737+ //virtual type get_type() {return TYPE_CONTEXT;}
738+ virtual unsigned get_num_items() { return 1; }
739+ virtual void enum_item(unsigned n, string_base & out) { out = (n==0 ? "Components/Mixi/YamabikoClient" : "");}
740+ virtual void perform_command(unsigned n)
741+ {
742+ TRACE_PLUGIN("menu_item_yamabiko::perform_command - enter");
743+
744+ if (n==0 && core_api::assert_main_thread())
745+ {
746+ cfg_enabled = !cfg_enabled;
747+ if (!cfg_enabled)
748+ {
749+ TRACE_PLUGIN("menu_item_yamabiko::perform_command - disable");
750+
751+ console::info("menu_item_yamabiko::perform_command - yamabiko disabled.");
752+ }
753+ else
754+ {
755+ TRACE_PLUGIN("menu_item_yamabiko::perform_command - enable");
756+
757+ console::info("menu_item_yamabiko::perform_command - yamabiko enabled.");
758+ }
759+ }
760+ }
761+ virtual bool is_checked(int n) {return n==0 ? !!cfg_enabled : false;}
762+};
763+
764+#define CLEARTYPE_QUALITY 5
765+
766+class config_fooyggd : public config
767+{
768+ static HFONT hIntervalFont;
769+
770+ static BOOL CALLBACK ConfigProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
771+ {
772+ HWND hYamabikoInterval1 = uGetDlgItem(wnd, IDC_YAMABIKO_INTERVAL_SLIDER_1ST);
773+ HWND hYamabikoInterval2 = uGetDlgItem(wnd, IDC_YAMABIKO_INTERVAL_SLIDER_2ND);
774+
775+ HWND hYamabikoInterval1Text = uGetDlgItem(wnd, IDC_YAMABIKO_INTERVAL_1ST);
776+ HWND hYamabikoInterval2Text = uGetDlgItem(wnd, IDC_YAMABIKO_INTERVAL_2ND);
777+
778+ switch(msg)
779+ {
780+ case WM_INITDIALOG:
781+ {
782+ HDC hWndDC = ::GetWindowDC(wnd);
783+ hIntervalFont = ::CreateFont(
784+ -MulDiv(20, GetDeviceCaps(hWndDC, LOGPIXELSY), 72), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
785+ ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, FIXED_PITCH, _T("Arial")
786+ );
787+ ::ReleaseDC(wnd, hWndDC);
788+
789+ uSendMessage(hYamabikoInterval1Text, WM_SETFONT, (WPARAM)hIntervalFont, (LPARAM)FALSE);
790+ uSendMessage(hYamabikoInterval2Text, WM_SETFONT, (WPARAM)hIntervalFont, (LPARAM)FALSE);
791+
792+ uSetDlgItemText(wnd,IDC_USERNAME,cfg_username);
793+ uSetDlgItemText(wnd,IDC_PASSWORD,cfg_password);
794+ uButton_SetCheck(wnd,IDC_YAMABIKO_ENABLED,(cfg_enabled == 1) ? true : false);
795+ uSetDlgItemText(wnd,IDC_YAMABIKO_INTERVAL_1ST,cfg_yamabiko_interval1);
796+ uSetDlgItemText(wnd,IDC_YAMABIKO_INTERVAL_2ND,cfg_yamabiko_interval2);
797+ uButton_SetCheck(wnd,IDC_PROXY_ENABLED,(cfg_proxy_enabled == 1) ? true : false);
798+ uSetDlgItemText(wnd,IDC_PROXY_SERVER,cfg_proxy_server);
799+ uSetDlgItemText(wnd,IDC_PROXY_PORT,cfg_proxy_port);
800+ uSetDlgItemText(wnd,IDC_PLUGIN_DESC, PLUGIN_CAPTION " " PLUGIN_VERSION PLUGIN_CAPTION2);
801+ uSetDlgItemText(wnd,IDC_VERSION_INFO, "build on " __DATE__ ", " __TIME__);
802+
803+ uSendMessage(hYamabikoInterval1, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(10, 120));
804+ uSendMessage(hYamabikoInterval1, TBM_SETLINESIZE, (WPARAM)0, (LPARAM)1);
805+ uSendMessage(hYamabikoInterval1, TBM_SETPAGESIZE, (WPARAM)0, (LPARAM)10);
806+ uSendMessage(hYamabikoInterval1, TBM_SETTICFREQ, (WPARAM)10, (LPARAM)0);
807+
808+ double pos1 = pfc_string_to_float(cfg_yamabiko_interval1);
809+ uSendMessage(hYamabikoInterval1, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos1);
810+
811+ uSendMessage(hYamabikoInterval2, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(50, 100));
812+ uSendMessage(hYamabikoInterval2, TBM_SETLINESIZE, (WPARAM)0, (LPARAM)1);
813+ uSendMessage(hYamabikoInterval2, TBM_SETPAGESIZE, (WPARAM)0, (LPARAM)5);
814+ uSendMessage(hYamabikoInterval2, TBM_SETTICFREQ, (WPARAM)5, (LPARAM)0);
815+
816+ double pos2 = pfc_string_to_float(cfg_yamabiko_interval2);
817+ uSendMessage(hYamabikoInterval2, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos2);
818+ }
819+ break;
820+ case WM_COMMAND:
821+ switch(wp)
822+ {
823+ case (EN_KILLFOCUS<<16)|IDC_USERNAME:
824+ cfg_username = string_utf8_from_window((HWND)lp);
825+ break;
826+ case (EN_KILLFOCUS<<16)|IDC_PASSWORD:
827+ cfg_password = string_utf8_from_window((HWND)lp);
828+ break;
829+ case (BN_CLICKED<<16)|IDC_YAMABIKO_ENABLED:
830+ cfg_enabled = uButton_GetCheck(wnd, IDC_YAMABIKO_ENABLED) ? 1 : 0;
831+ break;
832+ case (EN_KILLFOCUS<<16)|IDC_YAMABIKO_INTERVAL_1ST:
833+ cfg_yamabiko_interval1 = string_utf8_from_window((HWND)lp);
834+ break;
835+ case (EN_KILLFOCUS<<16)|IDC_YAMABIKO_INTERVAL_2ND:
836+ cfg_yamabiko_interval2 = string_utf8_from_window((HWND)lp);
837+ break;
838+ case (BN_CLICKED<<16)|IDC_PROXY_ENABLED:
839+ cfg_proxy_enabled = uButton_GetCheck(wnd, IDC_PROXY_ENABLED) ? 1 : 0;
840+ break;
841+ case (EN_KILLFOCUS<<16)|IDC_PROXY_SERVER:
842+ cfg_proxy_server = string_utf8_from_window((HWND)lp);
843+ break;
844+ case (EN_KILLFOCUS<<16)|IDC_PROXY_PORT:
845+ cfg_proxy_port = string_utf8_from_window((HWND)lp);
846+ break;
847+ }
848+ break;
849+ case WM_HSCROLL:
850+ {
851+ HWND hTrackBar = (HWND)lp;
852+
853+ if((hTrackBar == hYamabikoInterval1) || (hTrackBar == hYamabikoInterval2))
854+ {
855+ switch(LOWORD(wp))
856+ {
857+ case TB_THUMBPOSITION:
858+ case TB_THUMBTRACK:
859+ case TB_TOP:
860+ case TB_BOTTOM:
861+ case TB_PAGEUP:
862+ case TB_PAGEDOWN:
863+ case TB_LINEUP:
864+ case TB_LINEDOWN:
865+ case TB_ENDTRACK:
866+ {
867+ LONG lPos = 0;
868+
869+ switch(LOWORD(wp))
870+ {
871+ case TB_THUMBPOSITION:
872+ case TB_THUMBTRACK:
873+ lPos = HIWORD(wp);
874+ break;
875+ default:
876+ lPos = uSendMessage(hTrackBar, TBM_GETPOS, 0, 0);
877+ break;
878+ }
879+
880+ uSendMessage(hTrackBar, TBM_SETPOS, (WPARAM)TRUE, lPos);
881+
882+ if(hTrackBar == hYamabikoInterval1)
883+ {
884+ setDlgItemFloat(wnd, IDC_YAMABIKO_INTERVAL_1ST, (double)lPos);
885+ string8 pos;
886+ float2String(pos, (double)lPos);
887+ cfg_yamabiko_interval1 = pos;
888+ }
889+ else if(hTrackBar == hYamabikoInterval2)
890+ {
891+ setDlgItemFloat(wnd, IDC_YAMABIKO_INTERVAL_2ND, (double)lPos);
892+ string8 pos;
893+ float2String(pos, (double)lPos);
894+ cfg_yamabiko_interval2 = pos;
895+ }
896+ }
897+ break;
898+ default:
899+ break;
900+ }
901+ }
902+ }
903+ break;
904+ case WM_CLOSE:
905+ DeleteObject(hIntervalFont);
906+ break;
907+ }
908+
909+ return 0;
910+ }
911+
912+ static void setDlgItemFloat(HWND wnd, UINT id, double val)
913+ {
914+ string8 pos;
915+ float2String(pos, val);
916+
917+ uSetDlgItemText(wnd, id, pos);
918+ }
919+
920+ static void float2String(string8 &str, double val)
921+ {
922+ char *pStr = str.buffer_get(1024);
923+ pfc_float_to_string(pStr, val, 0);
924+ str.buffer_done();
925+ }
926+
927+public:
928+ virtual HWND create(HWND parent)
929+ {
930+ return uCreateDialog(IDD_CONFIG_DIALOGEX,parent,ConfigProc);
931+ }
932+ virtual const char * get_name() {return PLUGIN_CAPTION PLUGIN_CAPTION3;}
933+ virtual const char * get_parent_name() {return "Components";}
934+};
935+
936+HFONT config_fooyggd::hIntervalFont;
937+
938+static service_factory_single_t<play_callback, play_callback_yamabiko> foo1;
939+static service_factory_single_t<initquit, initquit_yamabiko> foo2;
940+static menu_item_factory<menu_item_yamabiko> foo3;
941+static service_factory_single_t<config,config_fooyggd> foo4;
942+
943+void DebugPrint(LPCSTR lpszFormat, ...)
944+{
945+ static Str64K buf;
946+ va_list marker;
947+
948+ va_start(marker, lpszFormat);
949+ vsprintf(buf, lpszFormat, marker);
950+ va_end(marker);
951+
952+ OutputDebugString(buf);
953+ OutputDebugString("\n");
954+
955+ string_utf8_from_ansi buf2(buf);
956+
957+ console::info(buf2);
958+}
--- /dev/null
+++ b/foo_mixi/foo_mixi.dsp
@@ -0,0 +1,123 @@
1+# Microsoft Developer Studio Project File - Name="foo_mixi" - Package Owner=<4>
2+# Microsoft Developer Studio Generated Build File, Format Version 6.00
3+# ** 編集しないでください **
4+
5+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
6+
7+CFG=foo_mixi - Win32 Debug
8+!MESSAGE これは有効なメイクファイルではありません。 このプロジェクトをビルドするためには NMAKE を使用してください。
9+!MESSAGE [メイクファイルのエクスポート] コマンドを使用して実行してください
10+!MESSAGE
11+!MESSAGE NMAKE /f "foo_mixi.mak".
12+!MESSAGE
13+!MESSAGE NMAKE の実行時に構成を指定できます
14+!MESSAGE コマンド ライン上でマクロの設定を定義します。例:
15+!MESSAGE
16+!MESSAGE NMAKE /f "foo_mixi.mak" CFG="foo_mixi - Win32 Debug"
17+!MESSAGE
18+!MESSAGE 選択可能なビルド モード:
19+!MESSAGE
20+!MESSAGE "foo_mixi - Win32 Release" ("Win32 (x86) Dynamic-Link Library" 用)
21+!MESSAGE "foo_mixi - Win32 Debug" ("Win32 (x86) Dynamic-Link Library" 用)
22+!MESSAGE
23+
24+# Begin Project
25+# PROP AllowPerConfigDependencies 0
26+# PROP Scc_ProjName ""
27+# PROP Scc_LocalPath ""
28+CPP=cl.exe
29+MTL=midl.exe
30+RSC=rc.exe
31+
32+!IF "$(CFG)" == "foo_mixi - Win32 Release"
33+
34+# PROP BASE Use_MFC 0
35+# PROP BASE Use_Debug_Libraries 0
36+# PROP BASE Output_Dir "Release"
37+# PROP BASE Intermediate_Dir "Release"
38+# PROP BASE Target_Dir ""
39+# PROP Use_MFC 0
40+# PROP Use_Debug_Libraries 0
41+# PROP Output_Dir "Release"
42+# PROP Intermediate_Dir "Release"
43+# PROP Ignore_Export_Lib 0
44+# PROP Target_Dir ""
45+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_MIXI_EXPORTS" /YX /FD /c
46+# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_MIXI_EXPORTS" /FD /c
47+# SUBTRACT CPP /YX
48+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
49+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
50+# ADD BASE RSC /l 0x411 /d "NDEBUG"
51+# ADD RSC /l 0x411 /d "NDEBUG"
52+BSC32=bscmake.exe
53+# ADD BASE BSC32 /nologo
54+# ADD BSC32 /nologo
55+LINK32=link.exe
56+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
57+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wxbase26_net.lib wxbase26.lib wsock32.lib /nologo /dll /machine:I386 /nodefaultlib:"LIBCMT" /out:"D:\Program Files\Media\foobar2000\components\foo_mixi.dll"
58+# SUBTRACT LINK32 /nodefaultlib
59+
60+!ELSEIF "$(CFG)" == "foo_mixi - Win32 Debug"
61+
62+# PROP BASE Use_MFC 0
63+# PROP BASE Use_Debug_Libraries 1
64+# PROP BASE Output_Dir "Debug"
65+# PROP BASE Intermediate_Dir "Debug"
66+# PROP BASE Target_Dir ""
67+# PROP Use_MFC 0
68+# PROP Use_Debug_Libraries 1
69+# PROP Output_Dir "Debug"
70+# PROP Intermediate_Dir "Debug"
71+# PROP Ignore_Export_Lib 0
72+# PROP Target_Dir ""
73+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_MIXI_EXPORTS" /YX /FD /GZ /c
74+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_MIXI_EXPORTS" /FD /GZ /c
75+# SUBTRACT CPP /YX
76+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
77+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
78+# ADD BASE RSC /l 0x411 /d "_DEBUG"
79+# ADD RSC /l 0x411 /d "_DEBUG"
80+BSC32=bscmake.exe
81+# ADD BASE BSC32 /nologo
82+# ADD BSC32 /nologo
83+LINK32=link.exe
84+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
85+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wxbase26d_net.lib wxbase26d.lib wsock32.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBCMTD" /out:"D:\Program Files\Media\foobar2000\components\foo_mixi.dll" /pdbtype:sept
86+# SUBTRACT LINK32 /nodefaultlib
87+
88+!ENDIF
89+
90+# Begin Target
91+
92+# Name "foo_mixi - Win32 Release"
93+# Name "foo_mixi - Win32 Debug"
94+# Begin Group "Source Files"
95+
96+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
97+# Begin Source File
98+
99+SOURCE=..\foobar2000_component_client\component_client.cpp
100+# End Source File
101+# Begin Source File
102+
103+SOURCE=.\foo_mixi.cpp
104+# End Source File
105+# Begin Source File
106+
107+SOURCE=.\foo_mixi.rc
108+# End Source File
109+# End Group
110+# Begin Group "Header Files"
111+
112+# PROP Default_Filter "h;hpp;hxx;hm;inl"
113+# Begin Source File
114+
115+SOURCE=.\resource.h
116+# End Source File
117+# End Group
118+# Begin Group "Resource Files"
119+
120+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
121+# End Group
122+# End Target
123+# End Project
--- /dev/null
+++ b/foo_mixi/foo_mixi.dsw
@@ -0,0 +1,92 @@
1+Microsoft Developer Studio Workspace File, Format Version 6.00
2+# 警告: このワークスペース ファイル を編集または削除しないでください!
3+
4+###############################################################################
5+
6+Project: "foo_mixi"=".\foo_mixi.dsp" - Package Owner=<4>
7+
8+Package=<5>
9+{{{
10+}}}
11+
12+Package=<4>
13+{{{
14+ Begin Project Dependency
15+ Project_Dep_Name foobar2000_SDK
16+ End Project Dependency
17+ Begin Project Dependency
18+ Project_Dep_Name foobar2000_sdk_helpers
19+ End Project Dependency
20+ Begin Project Dependency
21+ Project_Dep_Name pfc
22+ End Project Dependency
23+}}}
24+
25+###############################################################################
26+
27+Project: "foobar2000_SDK"="..\SDK\foobar2000_SDK.dsp" - Package Owner=<4>
28+
29+Package=<5>
30+{{{
31+}}}
32+
33+Package=<4>
34+{{{
35+ Begin Project Dependency
36+ Project_Dep_Name utf8api
37+ End Project Dependency
38+}}}
39+
40+###############################################################################
41+
42+Project: "foobar2000_sdk_helpers"="..\helpers\foobar2000_sdk_helpers.dsp" - Package Owner=<4>
43+
44+Package=<5>
45+{{{
46+}}}
47+
48+Package=<4>
49+{{{
50+}}}
51+
52+###############################################################################
53+
54+Project: "pfc"="..\..\pfc\pfc.dsp" - Package Owner=<4>
55+
56+Package=<5>
57+{{{
58+}}}
59+
60+Package=<4>
61+{{{
62+}}}
63+
64+###############################################################################
65+
66+Project: "utf8api"="..\utf8api\utf8api.dsp" - Package Owner=<4>
67+
68+Package=<5>
69+{{{
70+}}}
71+
72+Package=<4>
73+{{{
74+ Begin Project Dependency
75+ Project_Dep_Name pfc
76+ End Project Dependency
77+}}}
78+
79+###############################################################################
80+
81+Global:
82+
83+Package=<5>
84+{{{
85+}}}
86+
87+Package=<3>
88+{{{
89+}}}
90+
91+###############################################################################
92+
--- /dev/null
+++ b/foo_mixi/foo_mixi.rc
@@ -0,0 +1,222 @@
1+//Microsoft Developer Studio generated resource script.
2+//
3+#include "resource.h"
4+
5+#define APSTUDIO_READONLY_SYMBOLS
6+/////////////////////////////////////////////////////////////////////////////
7+//
8+// Generated from the TEXTINCLUDE 2 resource.
9+//
10+#include "afxres.h"
11+
12+/////////////////////////////////////////////////////////////////////////////
13+#undef APSTUDIO_READONLY_SYMBOLS
14+
15+/////////////////////////////////////////////////////////////////////////////
16+// 日本語 resources
17+
18+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
19+#ifdef _WIN32
20+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
21+#pragma code_page(932)
22+#endif //_WIN32
23+
24+#ifdef APSTUDIO_INVOKED
25+/////////////////////////////////////////////////////////////////////////////
26+//
27+// TEXTINCLUDE
28+//
29+
30+1 TEXTINCLUDE DISCARDABLE
31+BEGIN
32+ "resource.h\0"
33+END
34+
35+2 TEXTINCLUDE DISCARDABLE
36+BEGIN
37+ "#include ""afxres.h""\r\n"
38+ "\0"
39+END
40+
41+3 TEXTINCLUDE DISCARDABLE
42+BEGIN
43+ "\r\n"
44+ "\0"
45+END
46+
47+#endif // APSTUDIO_INVOKED
48+
49+
50+/////////////////////////////////////////////////////////////////////////////
51+//
52+// Dialog
53+//
54+
55+IDD_CONFIG_DIALOGEX DIALOGEX 0, 0, 275, 416
56+STYLE WS_CHILD
57+FONT 9, "MS UI Gothic", 400, 0, 0x80
58+BEGIN
59+ GROUPBOX "Yamabiko Settings",IDC_STATIC,7,7,261,87
60+ CONTROL "Yamabikoプラグインを有効にする",IDC_YAMABIKO_ENABLED,
61+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,19,247,13
62+ CONTROL "",IDC_YAMABIKO_INTERVAL_SLIDER_1ST,"msctls_trackbar32",
63+ TBS_AUTOTICKS | WS_TABSTOP,18,36,112,23,WS_EX_STATICEDGE
64+ EDITTEXT IDC_YAMABIKO_INTERVAL_1ST,132,36,44,23,ES_CENTER |
65+ ES_AUTOHSCROLL | ES_READONLY | ES_NUMBER | NOT
66+ WS_TABSTOP
67+ LTEXT "[秒] 以下の曲は送信禁止",IDC_STATIC,179,43,82,16,
68+ SS_CENTERIMAGE
69+ CONTROL "",IDC_YAMABIKO_INTERVAL_SLIDER_2ND,"msctls_trackbar32",
70+ TBS_AUTOTICKS | WS_TABSTOP,18,64,112,22,WS_EX_STATICEDGE
71+ EDITTEXT IDC_YAMABIKO_INTERVAL_2ND,132,64,44,22,ES_CENTER |
72+ ES_AUTOHSCROLL | ES_READONLY | ES_NUMBER | NOT
73+ WS_TABSTOP
74+ LTEXT "[%] 経過したら送信する",IDC_STATIC,179,70,82,16,
75+ SS_CENTERIMAGE
76+ RTEXT "Static",IDC_PLUGIN_DESC,7,109,261,14,SS_CENTERIMAGE
77+ RTEXT "Static",IDC_VERSION_INFO,7,129,261,14,SS_CENTERIMAGE
78+ CONTROL "Use HTTP Proxy",IDC_PROXY_ENABLED,"Button",
79+ BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED |
80+ WS_TABSTOP,14,168,247,14
81+ LTEXT "Server",IDC_STATIC,18,188,37,14,SS_CENTERIMAGE | NOT
82+ WS_VISIBLE | WS_DISABLED
83+ EDITTEXT IDC_PROXY_SERVER,55,188,206,14,ES_AUTOHSCROLL | NOT
84+ WS_VISIBLE | WS_DISABLED
85+ EDITTEXT IDC_PROXY_PORT,55,208,206,14,ES_AUTOHSCROLL | NOT
86+ WS_VISIBLE | WS_DISABLED
87+ LTEXT "Port",IDC_STATIC,14,208,39,14,SS_CENTERIMAGE | NOT
88+ WS_VISIBLE | WS_DISABLED
89+ GROUPBOX "Account Information for mixi",IDC_STATIC,7,235,261,58,
90+ NOT WS_VISIBLE | WS_DISABLED
91+ LTEXT "Username",IDC_STATIC,14,249,39,14,SS_CENTERIMAGE | NOT
92+ WS_VISIBLE | WS_DISABLED
93+ EDITTEXT IDC_USERNAME,55,249,206,14,ES_AUTOHSCROLL | NOT
94+ WS_VISIBLE | WS_DISABLED
95+ LTEXT "Password",IDC_STATIC,14,269,39,14,SS_CENTERIMAGE | NOT
96+ WS_VISIBLE | WS_DISABLED
97+ EDITTEXT IDC_PASSWORD,55,269,206,14,ES_PASSWORD | ES_AUTOHSCROLL |
98+ NOT WS_VISIBLE | WS_DISABLED
99+ GROUPBOX "HTTP Proxy",IDC_STATIC,7,156,261,73,NOT WS_VISIBLE |
100+ WS_DISABLED
101+ GROUPBOX "HTTP Proxy",IDC_STATIC,7,156,261,73,NOT WS_VISIBLE |
102+ WS_DISABLED
103+ LTEXT "Server",IDC_STATIC,18,188,37,14,SS_CENTERIMAGE | NOT
104+ WS_VISIBLE | WS_DISABLED
105+ LTEXT "Port",IDC_STATIC,14,208,39,14,SS_CENTERIMAGE | NOT
106+ WS_VISIBLE | WS_DISABLED
107+ EDITTEXT IDC_PROXY_SERVER2,55,188,206,14,ES_AUTOHSCROLL | NOT
108+ WS_VISIBLE | WS_DISABLED
109+ CONTROL "Use HTTP Proxy",IDC_PROXY_ENABLED2,"Button",
110+ BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED |
111+ WS_TABSTOP,14,168,247,14
112+END
113+
114+
115+/////////////////////////////////////////////////////////////////////////////
116+//
117+// DESIGNINFO
118+//
119+
120+#ifdef APSTUDIO_INVOKED
121+GUIDELINES DESIGNINFO MOVEABLE PURE
122+BEGIN
123+ IDD_CONFIG_DIALOGEX, DIALOG
124+ BEGIN
125+ LEFTMARGIN, 7
126+ RIGHTMARGIN, 268
127+ VERTGUIDE, 14
128+ VERTGUIDE, 18
129+ VERTGUIDE, 22
130+ VERTGUIDE, 53
131+ VERTGUIDE, 55
132+ VERTGUIDE, 88
133+ VERTGUIDE, 91
134+ VERTGUIDE, 130
135+ VERTGUIDE, 132
136+ VERTGUIDE, 176
137+ VERTGUIDE, 179
138+ VERTGUIDE, 261
139+ TOPMARGIN, 7
140+ BOTTOMMARGIN, 409
141+ HORZGUIDE, 19
142+ HORZGUIDE, 32
143+ HORZGUIDE, 36
144+ HORZGUIDE, 43
145+ HORZGUIDE, 59
146+ HORZGUIDE, 64
147+ HORZGUIDE, 70
148+ HORZGUIDE, 86
149+ HORZGUIDE, 94
150+ HORZGUIDE, 170
151+ HORZGUIDE, 184
152+ HORZGUIDE, 190
153+ HORZGUIDE, 204
154+ HORZGUIDE, 210
155+ HORZGUIDE, 224
156+ HORZGUIDE, 252
157+ HORZGUIDE, 268
158+ END
159+END
160+#endif // APSTUDIO_INVOKED
161+
162+
163+#ifndef _MAC
164+/////////////////////////////////////////////////////////////////////////////
165+//
166+// Version
167+//
168+
169+VS_VERSION_INFO VERSIONINFO
170+ FILEVERSION 0,0,0,4
171+ PRODUCTVERSION 0,0,0,4
172+ FILEFLAGSMASK 0x3fL
173+#ifdef _DEBUG
174+ FILEFLAGS 0x1L
175+#else
176+ FILEFLAGS 0x0L
177+#endif
178+ FILEOS 0x40004L
179+ FILETYPE 0x2L
180+ FILESUBTYPE 0x0L
181+BEGIN
182+ BLOCK "StringFileInfo"
183+ BEGIN
184+ BLOCK "041104b0"
185+ BEGIN
186+ VALUE "Comments", "YamabikoClient plugin for mixi, based on foobar2000 SDK 0.8.3\0"
187+ VALUE "CompanyName", "Yossie-pon Oniichan\0"
188+ VALUE "FileDescription", "YamabikoClient plugin for mixim based on foobar2000 SDK 0.8.3\0"
189+ VALUE "FileVersion", "0, 0, 0, 4\0"
190+ VALUE "InternalName", "foo_mixi\0"
191+ VALUE "LegalCopyright", "Copyright (C) 2006 Yossie-pon Oniichan, All Rights Reserved.\0"
192+ VALUE "LegalTrademarks", "YamabikoClient for foobar2000\0"
193+ VALUE "OriginalFilename", "foo_mixi.dll\0"
194+ VALUE "PrivateBuild", "\0"
195+ VALUE "ProductName", "foo_mixi.dll for foobar2000 v0.8.3 component plugin\0"
196+ VALUE "ProductVersion", "0, 0, 0, 4\0"
197+ VALUE "SpecialBuild", "\0"
198+ END
199+ END
200+ BLOCK "VarFileInfo"
201+ BEGIN
202+ VALUE "Translation", 0x411, 1200
203+ END
204+END
205+
206+#endif // !_MAC
207+
208+#endif // 日本語 resources
209+/////////////////////////////////////////////////////////////////////////////
210+
211+
212+
213+#ifndef APSTUDIO_INVOKED
214+/////////////////////////////////////////////////////////////////////////////
215+//
216+// Generated from the TEXTINCLUDE 3 resource.
217+//
218+
219+
220+/////////////////////////////////////////////////////////////////////////////
221+#endif // not APSTUDIO_INVOKED
222+
--- /dev/null
+++ b/foo_mixi/resource.h
@@ -0,0 +1,31 @@
1+//{{NO_DEPENDENCIES}}
2+// Microsoft Visual C++ generated include file.
3+// Used by foo_mixi.rc
4+//
5+#define IDD_CONFIG_DIALOGEX 101
6+#define IDC_USERNAME 1000
7+#define IDC_PASSWORD 1001
8+#define IDC_VERSION_INFO 1002
9+#define IDC_PLUGIN_DESC 1003
10+#define IDC_YAMABIKO_INTERVAL_1ST 1004
11+#define IDC_PROXY_SERVER 1005
12+#define IDC_PROXY_PORT 1006
13+#define IDC_YAMABIKO_ENABLED 1007
14+#define IDC_YAMABIKO_INTERVAL_2ND 1008
15+#define IDC_PROXY_ENABLED 1009
16+#define IDC_PROXY_SERVER2 1010
17+#define IDC_PROXY_ENABLED2 1011
18+#define IDC_YAMABIKO_INTERVAL_SLIDER_2ND 1012
19+#define IDC_SLIDER2 1013
20+#define IDC_YAMABIKO_INTERVAL_SLIDER_1ST 1013
21+
22+// Next default values for new objects
23+//
24+#ifdef APSTUDIO_INVOKED
25+#ifndef APSTUDIO_READONLY_SYMBOLS
26+#define _APS_NEXT_RESOURCE_VALUE 102
27+#define _APS_NEXT_COMMAND_VALUE 40001
28+#define _APS_NEXT_CONTROL_VALUE 1014
29+#define _APS_NEXT_SYMED_VALUE 101
30+#endif
31+#endif
--- /dev/null
+++ b/foo_yggd/foo_yggd.cpp
@@ -0,0 +1,641 @@
1+#include <windows.h>
2+#include <process.h>
3+#include <mmsystem.h>
4+#include <vector>
5+#include <memory>
6+#include "../SDK/foobar2000.h"
7+#include "../helpers/helpers.h"
8+#include "wx/protocol/http.h"
9+#include "wx/url.h"
10+#include "wx/sstream.h"
11+#include "resource.h"
12+
13+#define PLUGIN_CAPTION "YamabikoClient plugin"
14+#define PLUGIN_CAPTION2 " for Yggdrasil-System"
15+#define PLUGIN_CAPTION3 " (yggd)"
16+#define PLUGIN_VERSION "0.0.0.2"
17+
18+typedef char Str64K[65536];
19+
20+void DebugPrint(LPCSTR lpszFormat, ...);
21+
22+#define ENABLE_DEBUG true
23+#define ENABLE_DEBUG_TRACKINFO false
24+#define ENABLE_DEBUG_TRACKINFO_SHOW true
25+#define ENABLE_DEBUG_PLUGIN true
26+#define ENABLE_DEBUG_YGGD true
27+#define ENABLE_DEBUG_YGGD_ACCOUNT false
28+#define ENABLE_DEBUG_YGGD_ENCODE false
29+
30+#define TRACE(x) if(ENABLE_DEBUG) { OutputDebugString(x); OutputDebugString("\n"); console::info(x); }
31+#define TRACE_SJIS(x) if(ENABLE_DEBUG) { string_utf8_from_ansi tmp(x); OutputDebugString(x); OutputDebugString("\n"); console::info(tmp); }
32+
33+#define TRACE_TRACKINFO(x) if(ENABLE_DEBUG_TRACKINFO) TRACE(x)
34+#define TRACE_TRACKINFO_SHOW_SJIS(x) if(ENABLE_DEBUG_TRACKINFO_SHOW) TRACE_SJIS(x)
35+
36+#define TRACE_PLUGIN(x) if(ENABLE_DEBUG_PLUGIN) TRACE(x)
37+#define TRACE_PLUGIN_SJIS(x) if(ENABLE_DEBUG_PLUGIN) TRACE_SJIS(x)
38+
39+#define TRACE_YGGD(x) if(ENABLE_DEBUG_YGGD) TRACE(x)
40+#define TRACE_YGGD_SJIS(x) if(ENABLE_DEBUG_YGGD) TRACE_SJIS(x)
41+
42+#define TRACE_YGGD_ACCOUNT(x) if(ENABLE_DEBUG_YGGD_ENCODE) TRACE(x)
43+
44+#define TRACE_YGGD_ENCODE(x) if(ENABLE_DEBUG_YGGD_ENCODE) TRACE(x)
45+#define TRACE_YGGD_ENCODE_SJIS(x) if(ENABLE_DEBUG_YGGD_ENCODE) TRACE_SJIS(x)
46+
47+DECLARE_COMPONENT_VERSION(PLUGIN_CAPTION PLUGIN_CAPTION2, PLUGIN_VERSION, PLUGIN_CAPTION PLUGIN_CAPTION3);
48+
49+static cfg_int cfg_enabled("enabled",0);
50+
51+static cfg_string cfg_username("UserName","");
52+static cfg_string cfg_password("PassWord","");
53+
54+static cfg_string cfg_yamabiko_interval1("YamabikoInterval1","20");
55+static cfg_string cfg_yamabiko_interval2("YamabikoInterval2","120");
56+
57+static cfg_int cfg_proxy_enabled("useProxy",0);
58+static cfg_string cfg_proxy_server("ProxyServer","");
59+static cfg_string cfg_proxy_port("ProxyPort","");
60+
61+struct TRACK_INFO
62+{
63+ bool m_isEmpty;
64+ wxString m_title;
65+ wxString m_album;
66+ wxString m_artist;
67+ wxString m_genre;
68+
69+ TRACK_INFO() : m_isEmpty(true) {}
70+
71+ void set(LPCSTR title, LPCSTR album, LPCSTR artist, LPCSTR genre)
72+ {
73+ TRACE_TRACKINFO("TRACK_INFO::set - called.");
74+
75+ if(title) m_title = title; else m_title.Clear();
76+ if(album) m_album = album; else m_album.Clear();
77+ if(artist) m_artist = artist; else m_artist.Clear();
78+ if(genre) m_genre = genre; else m_genre.Clear();
79+
80+ m_isEmpty = false;
81+ }
82+
83+ void clear()
84+ {
85+ TRACE_TRACKINFO("TRACK_INFO::clear - called.");
86+
87+ m_title.Clear();
88+ m_album.Clear();
89+ m_artist.Clear();
90+ m_genre.Clear();
91+
92+ m_isEmpty = true;
93+ }
94+
95+ void show() const
96+ {
97+ if(!m_title.IsEmpty()) { TRACE_TRACKINFO_SHOW_SJIS(m_title); } else { TRACE_TRACKINFO("title null."); }
98+ if(!m_album.IsEmpty()) { TRACE_TRACKINFO_SHOW_SJIS(m_album); } else { TRACE_TRACKINFO("album null."); }
99+ if(!m_artist.IsEmpty()) { TRACE_TRACKINFO_SHOW_SJIS(m_artist); } else { TRACE_TRACKINFO("artist null."); }
100+ if(!m_genre.IsEmpty()) { TRACE_TRACKINFO_SHOW_SJIS(m_genre); } else { TRACE_TRACKINFO("genre null."); }
101+ }
102+
103+ bool isEmpty() const { return m_isEmpty; }
104+};
105+
106+class yggdrasil
107+{
108+public:
109+
110+ void setAccountInfo(LPCSTR user, LPCSTR pass)
111+ {
112+ TRACE_YGGD_ACCOUNT("yggdrasil::setAccountInfo - called.");
113+ TRACE_YGGD_ACCOUNT(user);
114+ TRACE_YGGD_ACCOUNT(pass);
115+
116+ m_username = encodeURL(user);
117+ m_password = encodeURL(pass);
118+// m_username = user;
119+// m_password = pass;
120+ }
121+
122+ bool postYamabiko(const TRACK_INFO &info)
123+ {
124+ TRACE_YGGD("yggdrasil::postYamabiko - enter.");
125+
126+ if(m_sessionid.IsEmpty())
127+ {
128+ if(!login())
129+ {
130+ TRACE_YGGD("yggdrasil::postYamabiko - first login failed.");
131+ return false;
132+ }
133+ }
134+
135+ wxString yamabiko;
136+ yamabiko = createYamabiko(info);
137+
138+ if(!do_post("/do.php", yamabiko))
139+ {
140+ if(!login())
141+ {
142+ TRACE_YGGD("yggdrasil::postYamabiko - relogin failed.");
143+ return false;
144+ }
145+
146+ yamabiko = createYamabiko(info);
147+
148+ if(!do_post("/do.php", yamabiko))
149+ {
150+ TRACE_YGGD("yggdrasil::postYamabiko - post yamabiko failed after logged in.");
151+ return false;
152+ }
153+ else
154+ {
155+ TRACE_YGGD("yggdrasil::postYamabiko - yamabiko posted successfully after logged in.");
156+ }
157+ }
158+ else
159+ {
160+ TRACE_YGGD("yggdrasil::postYamabiko - yamabiko posted successfully.");
161+ }
162+
163+ TRACE_YGGD("yggdrasil::postYamabiko - exit.");
164+
165+ return true;
166+ }
167+
168+ bool login()
169+ {
170+ TRACE_YGGD("yggdrasil::login - enter.");
171+
172+ wxString postBuf(
173+ wxString::Format(
174+ "cmd=login&s=y&from=login&username=%s&password=%s",
175+ (LPCSTR)m_username, (LPCSTR)m_password
176+ )
177+ );
178+
179+ if(!do_post("/do_normal.php", postBuf, true))
180+ {
181+ TRACE_YGGD("yggdrasil::login - post method failed.");
182+ return false;
183+ }
184+
185+ if(m_body == "boo")
186+ {
187+ TRACE_YGGD("yggdrasil::login - login failed.");
188+ return false;
189+ }
190+
191+ TRACE_YGGD("yggdrasil::login - successfully logged in.");
192+
193+ return true;
194+ }
195+
196+protected:
197+
198+ bool do_post(LPCSTR path, LPCSTR postBuf, bool isLogin = false)
199+ {
200+ TRACE_YGGD("yggdrasil::do_post - enter.");
201+
202+ wxString host("http://yggdrasil-system.com");
203+ host += path;
204+ wxURL url(host);
205+
206+ if(cfg_proxy_enabled == 1)
207+ {
208+ wxString proxyURL(cfg_proxy_server);
209+ wxString proxyPort(cfg_proxy_port);
210+ if(proxyPort.Length() > 0)
211+ {
212+ proxyURL += ":";
213+ proxyURL += proxyPort;
214+ }
215+ url.SetProxy(proxyURL);
216+ TRACE_YGGD(proxyURL);
217+ }
218+
219+ wxHTTP &http = static_cast<wxHTTP &>(url.GetProtocol());
220+
221+ wxString PHPSESSIONID;
222+
223+ if(!m_sessionid.IsEmpty())
224+ {
225+ PHPSESSIONID = wxString::Format("PHPSESSID=%s", (LPCSTR)m_sessionid);
226+ }
227+
228+ http.SetHeader("Content-Type", "application/x-www-form-urlencoded");
229+
230+ if(!(PHPSESSIONID.IsEmpty() || isLogin))
231+ {
232+ http.SetHeader("Cookie", PHPSESSIONID);
233+ }
234+
235+ http.SetPostBuffer(postBuf);
236+
237+ TRACE_YGGD( path );
238+ TRACE_YGGD( postBuf );
239+
240+// std::auto_ptr<wxInputStream> in( http.GetInputStream( wxT(path) ) );
241+ std::auto_ptr<wxInputStream> in( url.GetInputStream() );
242+ std::auto_ptr<wxStringOutputStream> out( new wxStringOutputStream() );
243+
244+ m_response = http.GetResponse();
245+
246+ if(m_response == 200)
247+ {
248+ TRACE_YGGD("yggdrasil::do_post - 200 post succeeded.");
249+
250+ in->Read(*out);
251+ m_body = out->GetString();
252+
253+ TRACE_YGGD_SJIS( m_body );
254+
255+ if(isLogin)
256+ {
257+ if(m_body != "Boo")
258+ {
259+ m_sessionid = m_body;
260+
261+ TRACE_YGGD("yggdrasil::do_post - got session id successfully");
262+ }
263+ else
264+ {
265+ TRACE_YGGD("yggdrasil::do_post - exit with boo");
266+ return false;
267+ }
268+ }
269+ else
270+ {
271+ if(m_body == "ok")
272+ {
273+ TRACE_YGGD("yggdrasil::do_post - status ok");
274+ }
275+ else
276+ {
277+ TRACE_YGGD("yggdrasil::do_post - exit with boo");
278+ return false;
279+ }
280+ }
281+
282+ TRACE_YGGD("yggdrasil::do_post - exit with ok, status 200");
283+ return true;
284+ }
285+ else
286+ {
287+ m_body.Clear();
288+ TRACE_YGGD("yggdrasil::do_post - exit with bad status");
289+ return false;
290+ }
291+ }
292+
293+ wxString createYamabiko(const TRACK_INFO &info)
294+ {
295+ TRACK_INFO encodedInfo;
296+
297+ info.show();
298+
299+ encodedInfo.set(
300+ encodeURL(info.m_title),
301+ encodeURL(info.m_album),
302+ encodeURL(info.m_artist),
303+ encodeURL(info.m_genre)
304+ );
305+
306+ wxString path(
307+ wxString::Format(
308+ "sessid=%s&cmd=h_now_playing_update&playing_title=%s&playing_album=%s&playing_airtist=%s&playing_jle=%s",
309+ m_sessionid, encodedInfo.m_title, encodedInfo.m_album, encodedInfo.m_artist, encodedInfo.m_genre
310+ )
311+ );
312+
313+ return path;
314+ }
315+
316+ wxString encodeURL(LPCSTR srcStr)
317+ {
318+ wxString temp(srcStr);
319+ return encodeURL(temp);
320+ }
321+
322+ wxString encodeURL(const wxString &srcStr)
323+ {
324+ TRACE_YGGD_ENCODE("TRACK_INFO::encodeURL - enter.");
325+ TRACE_YGGD_ENCODE_SJIS(srcStr);
326+
327+ size_t srcStrLen = srcStr.Length();
328+ //DebugPrint("length - %d", srcStrLen);
329+
330+ wxString dstStr;
331+ char *dstPtr = dstStr.GetWriteBuf(srcStrLen * 3 + 1);
332+
333+ for(const char *srcPtr = srcStr; *srcPtr != '\0'; srcPtr ++)
334+ {
335+ unsigned char c = *srcPtr;
336+
337+ if(
338+ ((c >= 'a') && (c <= 'z')) ||
339+ ((c >= 'A') && (c <= 'Z')) ||
340+ ((c >= '0') && (c <= '9')) ||
341+ (strchr("-_.!~*'()", c) != NULL)
342+ ){
343+ *dstPtr ++ = c;
344+ }
345+ else
346+ {
347+ *dstPtr ++ = '%';
348+ *dstPtr ++ = hex(c >> 4);
349+ *dstPtr ++ = hex(c & 0x0f);
350+ }
351+ }
352+
353+ *dstPtr = '\0';
354+ dstStr.UngetWriteBuf();
355+
356+ TRACE_YGGD_ENCODE(dstStr);
357+ TRACE_YGGD_ENCODE("TRACK_INFO::encode - exit.");
358+
359+ return dstStr;
360+ }
361+
362+ char hex(char val)
363+ {
364+ return (val < 10) ? '0' + val : 'a' + (val - 10);
365+ }
366+
367+ int m_response; //!< http response code
368+ wxString m_username; //!< user account name
369+ wxString m_password; //!< password
370+ wxString m_body; //!< http response body
371+ wxString m_sessionid; //!< http cookie php session id
372+};
373+
374+class play_callback_yamabiko : public play_callback
375+{
376+ yggdrasil m_yggd;
377+ double m_previous_sec;
378+ bool m_sendonce;
379+
380+ virtual void on_playback_starting()
381+ {
382+ if(!cfg_enabled) return;
383+
384+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_starting called.");
385+
386+ // do something
387+ }
388+
389+ virtual void on_playback_new_track(metadb_handle * track)
390+ {
391+ if(!cfg_enabled) return;
392+
393+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_new_track called.");
394+
395+ // reset send timing
396+ resetSendTiming();
397+ }
398+
399+ virtual void on_playback_stop(play_control::stop_reason reason)
400+ {
401+ if(!cfg_enabled) return;
402+
403+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_stop called.");
404+
405+ // do something
406+ }
407+
408+ // timeは秒
409+ virtual void on_playback_seek(double time)
410+ {
411+ if(!cfg_enabled) return;
412+
413+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_seek called.");
414+
415+ // reset send timing
416+ resetSendTiming();
417+ }
418+
419+ virtual void on_playback_pause(int state)
420+ {
421+ if(!cfg_enabled) return;
422+
423+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_pause called.");
424+
425+ // do something
426+ }
427+
428+ virtual void on_playback_edited(metadb_handle * track){}//currently played file got edited
429+
430+ virtual void on_playback_dynamic_info(const file_info * info,bool b_track_change){}
431+
432+ virtual void on_playback_time(metadb_handle * track,double val) //called every second
433+ {
434+ if(!cfg_enabled) return;
435+
436+ if(checkSendTiming(val) == true)
437+ {
438+ TRACE_PLUGIN("play_callback_yamabiko::on_playback_time called, interval-time elapsed.");
439+ TRACE_PLUGIN("sending: currently playbacked track informations ...");
440+
441+ TRACK_INFO info;
442+
443+ // get currently playbacked track informations
444+ string8 title_utf8;
445+ string8 album_utf8;
446+ string8 artist_utf8;
447+ string8 genre_utf8;
448+
449+ track->handle_format_title(title_utf8, "%title%", 0);
450+ track->handle_format_title(album_utf8, "%album%", 0);
451+ track->handle_format_title(artist_utf8, "%artist%", 0);
452+ track->handle_format_title(genre_utf8, "%genre%", 0);
453+
454+ string_ansi_from_utf8 title(title_utf8);
455+ string_ansi_from_utf8 album(album_utf8);
456+ string_ansi_from_utf8 artist(artist_utf8);
457+ string_ansi_from_utf8 genre(genre_utf8);
458+
459+ // set informations
460+ info.set(title, album, artist, genre);
461+
462+ // sending track informations
463+ do_post(info);
464+ }
465+ }
466+
467+ // virtual void on_volume_change(int new_val) {}//may also happen when not playing
468+
469+ void do_post(const TRACK_INFO &info)
470+ {
471+ TRACE_PLUGIN("play_callback_yamabiko::doPost - enter");
472+
473+ if(info.isEmpty() == false)
474+ {
475+ m_yggd.setAccountInfo(cfg_username, cfg_password);
476+ if(m_yggd.postYamabiko(info) == true)
477+ {
478+ m_sendonce = true;
479+ }
480+ }
481+
482+ TRACE_PLUGIN("play_callback_yamabiko::doPost - exit");
483+ }
484+
485+ void resetSendTiming()
486+ {
487+ TRACE_PLUGIN("play_callback_yamabiko::resetSendTiming - called");
488+ m_previous_sec = -1.0;
489+ m_sendonce = false;
490+ }
491+
492+ bool checkSendTiming(double sec)
493+ {
494+ double interval;
495+
496+ if(m_sendonce)
497+ {
498+ interval = pfc_string_to_float(cfg_yamabiko_interval2);
499+ }
500+ else
501+ {
502+ interval = pfc_string_to_float(cfg_yamabiko_interval1);
503+ }
504+
505+ if(interval < 10.0) interval = 10.0;
506+
507+ if(m_previous_sec < 0.0)
508+ {
509+ m_previous_sec = sec;
510+ }
511+
512+ if(sec - m_previous_sec > interval)
513+ {
514+ m_previous_sec = sec;
515+ return true;
516+ }
517+
518+ return false;
519+ }
520+};
521+
522+class initquit_yamabiko : public initquit
523+{
524+ virtual void on_init()
525+ {
526+ // do something
527+ }
528+
529+ virtual void on_quit()
530+ {
531+ // do something
532+ }
533+};
534+
535+class menu_item_yamabiko : public menu_item_main
536+{
537+ //virtual type get_type() {return TYPE_CONTEXT;}
538+ virtual unsigned get_num_items() { return 1; }
539+ virtual void enum_item(unsigned n, string_base & out) { out = (n==0 ? "Components/Yggdrasil/YamabikoClient" : "");}
540+ virtual void perform_command(unsigned n)
541+ {
542+ TRACE_PLUGIN("menu_item_yamabiko::perform_command - enter");
543+
544+ if (n==0 && core_api::assert_main_thread())
545+ {
546+ cfg_enabled = !cfg_enabled;
547+ if (!cfg_enabled)
548+ {
549+ TRACE_PLUGIN("menu_item_yamabiko::perform_command - disable");
550+
551+ console::info("menu_item_yamabiko::perform_command - yamabiko disabled.");
552+ }
553+ else
554+ {
555+ TRACE_PLUGIN("menu_item_yamabiko::perform_command - enable");
556+
557+ console::info("menu_item_yamabiko::perform_command - yamabiko enabled.");
558+ }
559+ }
560+ }
561+ virtual bool is_checked(int n) {return n==0 ? !!cfg_enabled : false;}
562+};
563+
564+class config_fooyggd : public config
565+{
566+ static BOOL CALLBACK ConfigProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
567+ {
568+ switch(msg)
569+ {
570+ case WM_INITDIALOG:
571+ uSetDlgItemText(wnd,IDC_USERNAME,cfg_username);
572+ uSetDlgItemText(wnd,IDC_PASSWORD,cfg_password);
573+ uButton_SetCheck(wnd,IDC_YAMABIKO_ENABLED,(cfg_enabled == 1) ? true : false);
574+ uSetDlgItemText(wnd,IDC_YAMABIKO_INTERVAL_1ST,cfg_yamabiko_interval1);
575+ uSetDlgItemText(wnd,IDC_YAMABIKO_INTERVAL_2ND,cfg_yamabiko_interval2);
576+ uButton_SetCheck(wnd,IDC_PROXY_ENABLED,(cfg_proxy_enabled == 1) ? true : false);
577+ uSetDlgItemText(wnd,IDC_PROXY_SERVER,cfg_proxy_server);
578+ uSetDlgItemText(wnd,IDC_PROXY_PORT,cfg_proxy_port);
579+ uSetDlgItemText(wnd,IDC_PLUGIN_DESC, PLUGIN_CAPTION " " PLUGIN_VERSION PLUGIN_CAPTION2);
580+ uSetDlgItemText(wnd,IDC_VERSION_INFO, "build on " __DATE__ ", " __TIME__);
581+ break;
582+ case WM_COMMAND:
583+ switch(wp)
584+ {
585+ case (EN_KILLFOCUS<<16)|IDC_USERNAME:
586+ cfg_username = string_utf8_from_window((HWND)lp);
587+ break;
588+ case (EN_KILLFOCUS<<16)|IDC_PASSWORD:
589+ cfg_password = string_utf8_from_window((HWND)lp);
590+ break;
591+ case (BN_CLICKED<<16)|IDC_YAMABIKO_ENABLED:
592+ cfg_enabled = uButton_GetCheck(wnd, IDC_YAMABIKO_ENABLED) ? 1 : 0;
593+ break;
594+ case (EN_KILLFOCUS<<16)|IDC_YAMABIKO_INTERVAL_1ST:
595+ cfg_yamabiko_interval1 = string_utf8_from_window((HWND)lp);
596+ break;
597+ case (EN_KILLFOCUS<<16)|IDC_YAMABIKO_INTERVAL_2ND:
598+ cfg_yamabiko_interval2 = string_utf8_from_window((HWND)lp);
599+ break;
600+ case (BN_CLICKED<<16)|IDC_PROXY_ENABLED:
601+ cfg_proxy_enabled = uButton_GetCheck(wnd, IDC_PROXY_ENABLED) ? 1 : 0;
602+ break;
603+ case (EN_KILLFOCUS<<16)|IDC_PROXY_SERVER:
604+ cfg_proxy_server = string_utf8_from_window((HWND)lp);
605+ break;
606+ case (EN_KILLFOCUS<<16)|IDC_PROXY_PORT:
607+ cfg_proxy_port = string_utf8_from_window((HWND)lp);
608+ break;
609+ }
610+ break;
611+ }
612+
613+ return 0;
614+ }
615+public:
616+ virtual HWND create(HWND parent)
617+ {
618+ return uCreateDialog(IDD_CONFIG_DIALOGEX,parent,ConfigProc);
619+ }
620+ virtual const char * get_name() {return PLUGIN_CAPTION PLUGIN_CAPTION3;}
621+ virtual const char * get_parent_name() {return "Components";}
622+};
623+
624+static service_factory_single_t<play_callback, play_callback_yamabiko> foo1;
625+static service_factory_single_t<initquit, initquit_yamabiko> foo2;
626+static menu_item_factory<menu_item_yamabiko> foo3;
627+static service_factory_single_t<config,config_fooyggd> foo4;
628+
629+void DebugPrint(LPCSTR lpszFormat, ...)
630+{
631+ static Str64K buf;
632+ va_list marker;
633+
634+ va_start(marker, lpszFormat);
635+ vsprintf(buf, lpszFormat, marker);
636+ va_end(marker);
637+
638+ OutputDebugString(buf);
639+ OutputDebugString("\n");
640+ console::info(buf);
641+}
--- /dev/null
+++ b/foo_yggd/foo_yggd.dsp
@@ -0,0 +1,116 @@
1+# Microsoft Developer Studio Project File - Name="foo_yggd" - Package Owner=<4>
2+# Microsoft Developer Studio Generated Build File, Format Version 6.00
3+# ** 編集しないでください **
4+
5+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
6+
7+CFG=foo_yggd - Win32 Debug
8+!MESSAGE これは有効なメイクファイルではありません。 このプロジェクトをビルドするためには NMAKE を使用してください。
9+!MESSAGE [メイクファイルのエクスポート] コマンドを使用して実行してください
10+!MESSAGE
11+!MESSAGE NMAKE /f "foo_yggd.mak".
12+!MESSAGE
13+!MESSAGE NMAKE の実行時に構成を指定できます
14+!MESSAGE コマンド ライン上でマクロの設定を定義します。例:
15+!MESSAGE
16+!MESSAGE NMAKE /f "foo_yggd.mak" CFG="foo_yggd - Win32 Debug"
17+!MESSAGE
18+!MESSAGE 選択可能なビルド モード:
19+!MESSAGE
20+!MESSAGE "foo_yggd - Win32 Release" ("Win32 (x86) Dynamic-Link Library" 用)
21+!MESSAGE "foo_yggd - Win32 Debug" ("Win32 (x86) Dynamic-Link Library" 用)
22+!MESSAGE
23+
24+# Begin Project
25+# PROP AllowPerConfigDependencies 0
26+# PROP Scc_ProjName ""
27+# PROP Scc_LocalPath ""
28+CPP=cl.exe
29+MTL=midl.exe
30+RSC=rc.exe
31+
32+!IF "$(CFG)" == "foo_yggd - Win32 Release"
33+
34+# PROP BASE Use_MFC 0
35+# PROP BASE Use_Debug_Libraries 0
36+# PROP BASE Output_Dir "Release"
37+# PROP BASE Intermediate_Dir "Release"
38+# PROP BASE Target_Dir ""
39+# PROP Use_MFC 0
40+# PROP Use_Debug_Libraries 0
41+# PROP Output_Dir "Release"
42+# PROP Intermediate_Dir "Release"
43+# PROP Ignore_Export_Lib 0
44+# PROP Target_Dir ""
45+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_YGGD_EXPORTS" /YX /FD /c
46+# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_YGGD_EXPORTS" /FD /c
47+# SUBTRACT CPP /YX
48+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
49+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
50+# ADD BASE RSC /l 0x411 /d "NDEBUG"
51+# ADD RSC /l 0x411 /d "NDEBUG"
52+BSC32=bscmake.exe
53+# ADD BASE BSC32 /nologo
54+# ADD BSC32 /nologo
55+LINK32=link.exe
56+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
57+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wxbase26_net.lib wxbase26.lib wsock32.lib /nologo /dll /machine:I386 /nodefaultlib:"LIBCMT" /out:"C:\Program Files\Media\foobar2000\components\foo_yggd.dll"
58+
59+!ELSEIF "$(CFG)" == "foo_yggd - Win32 Debug"
60+
61+# PROP BASE Use_MFC 0
62+# PROP BASE Use_Debug_Libraries 1
63+# PROP BASE Output_Dir "Debug"
64+# PROP BASE Intermediate_Dir "Debug"
65+# PROP BASE Target_Dir ""
66+# PROP Use_MFC 0
67+# PROP Use_Debug_Libraries 1
68+# PROP Output_Dir "Debug"
69+# PROP Intermediate_Dir "Debug"
70+# PROP Ignore_Export_Lib 0
71+# PROP Target_Dir ""
72+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_YGGD_EXPORTS" /YX /FD /GZ /c
73+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_YGGD_EXPORTS" /YX /FD /GZ /c
74+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
75+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
76+# ADD BASE RSC /l 0x411 /d "_DEBUG"
77+# ADD RSC /l 0x411 /d "_DEBUG"
78+BSC32=bscmake.exe
79+# ADD BASE BSC32 /nologo
80+# ADD BSC32 /nologo
81+LINK32=link.exe
82+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
83+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wxbase26d_net.lib wxbase26d.lib wsock32.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBCMTD" /out:"C:\Program Files\Media\foobar2000\components\foo_yggd.dll" /pdbtype:sept
84+
85+!ENDIF
86+
87+# Begin Target
88+
89+# Name "foo_yggd - Win32 Release"
90+# Name "foo_yggd - Win32 Debug"
91+# Begin Group "Source Files"
92+
93+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
94+# Begin Source File
95+
96+SOURCE=..\foobar2000_component_client\component_client.cpp
97+# End Source File
98+# Begin Source File
99+
100+SOURCE=.\foo_yggd.cpp
101+# End Source File
102+# Begin Source File
103+
104+SOURCE=.\foo_yggd.rc
105+# End Source File
106+# End Group
107+# Begin Group "Header Files"
108+
109+# PROP Default_Filter "h;hpp;hxx;hm;inl"
110+# End Group
111+# Begin Group "Resource Files"
112+
113+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
114+# End Group
115+# End Target
116+# End Project
--- /dev/null
+++ b/foo_yggd/foo_yggd.dsw
@@ -0,0 +1,92 @@
1+Microsoft Developer Studio Workspace File, Format Version 6.00
2+# 警告: このワークスペース ファイル を編集または削除しないでください!
3+
4+###############################################################################
5+
6+Project: "foo_yggd"=".\foo_yggd.dsp" - Package Owner=<4>
7+
8+Package=<5>
9+{{{
10+}}}
11+
12+Package=<4>
13+{{{
14+ Begin Project Dependency
15+ Project_Dep_Name foobar2000_SDK
16+ End Project Dependency
17+ Begin Project Dependency
18+ Project_Dep_Name foobar2000_sdk_helpers
19+ End Project Dependency
20+ Begin Project Dependency
21+ Project_Dep_Name pfc
22+ End Project Dependency
23+}}}
24+
25+###############################################################################
26+
27+Project: "foobar2000_SDK"="..\SDK\foobar2000_SDK.dsp" - Package Owner=<4>
28+
29+Package=<5>
30+{{{
31+}}}
32+
33+Package=<4>
34+{{{
35+ Begin Project Dependency
36+ Project_Dep_Name utf8api
37+ End Project Dependency
38+}}}
39+
40+###############################################################################
41+
42+Project: "foobar2000_sdk_helpers"="..\helpers\foobar2000_sdk_helpers.dsp" - Package Owner=<4>
43+
44+Package=<5>
45+{{{
46+}}}
47+
48+Package=<4>
49+{{{
50+}}}
51+
52+###############################################################################
53+
54+Project: "pfc"="..\..\pfc\pfc.dsp" - Package Owner=<4>
55+
56+Package=<5>
57+{{{
58+}}}
59+
60+Package=<4>
61+{{{
62+}}}
63+
64+###############################################################################
65+
66+Project: "utf8api"="..\utf8api\utf8api.dsp" - Package Owner=<4>
67+
68+Package=<5>
69+{{{
70+}}}
71+
72+Package=<4>
73+{{{
74+ Begin Project Dependency
75+ Project_Dep_Name pfc
76+ End Project Dependency
77+}}}
78+
79+###############################################################################
80+
81+Global:
82+
83+Package=<5>
84+{{{
85+}}}
86+
87+Package=<3>
88+{{{
89+}}}
90+
91+###############################################################################
92+
--- /dev/null
+++ b/foo_yggd/foo_yggd.rc
@@ -0,0 +1,190 @@
1+//Microsoft Developer Studio generated resource script.
2+//
3+#include "resource.h"
4+
5+#define APSTUDIO_READONLY_SYMBOLS
6+/////////////////////////////////////////////////////////////////////////////
7+//
8+// Generated from the TEXTINCLUDE 2 resource.
9+//
10+#include "afxres.h"
11+
12+/////////////////////////////////////////////////////////////////////////////
13+#undef APSTUDIO_READONLY_SYMBOLS
14+
15+/////////////////////////////////////////////////////////////////////////////
16+// 日本語 resources
17+
18+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
19+#ifdef _WIN32
20+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
21+#pragma code_page(932)
22+#endif //_WIN32
23+
24+#ifdef APSTUDIO_INVOKED
25+/////////////////////////////////////////////////////////////////////////////
26+//
27+// TEXTINCLUDE
28+//
29+
30+1 TEXTINCLUDE DISCARDABLE
31+BEGIN
32+ "resource.h\0"
33+END
34+
35+2 TEXTINCLUDE DISCARDABLE
36+BEGIN
37+ "#include ""afxres.h""\r\n"
38+ "\0"
39+END
40+
41+3 TEXTINCLUDE DISCARDABLE
42+BEGIN
43+ "\r\n"
44+ "\0"
45+END
46+
47+#endif // APSTUDIO_INVOKED
48+
49+
50+/////////////////////////////////////////////////////////////////////////////
51+//
52+// Dialog
53+//
54+
55+IDD_CONFIG_DIALOGEX DIALOG DISCARDABLE 0, 0, 220, 277
56+STYLE WS_CHILD
57+FONT 9, "MS Pゴシック"
58+BEGIN
59+ LTEXT "Username",IDC_STATIC,14,21,39,14,SS_CENTERIMAGE
60+ GROUPBOX "Account Information for Yggdrasil-System",IDC_STATIC,7,
61+ 7,206,58
62+ LTEXT "Password",IDC_STATIC,14,41,39,14,SS_CENTERIMAGE
63+ EDITTEXT IDC_USERNAME,55,21,152,14,ES_AUTOHSCROLL
64+ EDITTEXT IDC_PASSWORD,55,41,152,14,ES_PASSWORD | ES_AUTOHSCROLL
65+ RTEXT "Static",IDC_VERSION_INFO,7,254,206,14,SS_CENTERIMAGE
66+ RTEXT "Static",IDC_PLUGIN_DESC,7,238,206,14,SS_CENTERIMAGE
67+ GROUPBOX "Yamabiko Settings",IDC_STATIC,7,74,206,73
68+ LTEXT "Interval 1st",IDC_STATIC,14,105,39,14,SS_CENTERIMAGE
69+ EDITTEXT IDC_YAMABIKO_INTERVAL_1ST,55,105,60,14,ES_AUTOHSCROLL
70+ LTEXT "[sec.]",IDC_STATIC,120,105,87,14,SS_CENTERIMAGE
71+ GROUPBOX "HTTP Proxy",IDC_STATIC,7,158,206,73
72+ LTEXT "Server",IDC_STATIC,16,190,39,14,SS_CENTERIMAGE
73+ LTEXT "Port",IDC_STATIC,14,210,39,14,SS_CENTERIMAGE
74+ EDITTEXT IDC_PROXY_SERVER,55,190,152,14,ES_AUTOHSCROLL
75+ EDITTEXT IDC_PROXY_PORT,55,210,152,14,ES_AUTOHSCROLL
76+ CONTROL "Enable Yamabiko Plugin",IDC_YAMABIKO_ENABLED,"Button",
77+ BS_AUTOCHECKBOX | WS_TABSTOP,14,86,193,13
78+ LTEXT "Interval 2nd",IDC_STATIC,14,125,39,14,SS_CENTERIMAGE
79+ EDITTEXT IDC_YAMABIKO_INTERVAL_2ND,55,125,60,14,ES_AUTOHSCROLL
80+ LTEXT "[sec.]",IDC_STATIC,120,125,87,14,SS_CENTERIMAGE
81+ CONTROL "Use HTTP Proxy",IDC_PROXY_ENABLED,"Button",
82+ BS_AUTOCHECKBOX | WS_TABSTOP,14,170,193,14
83+END
84+
85+
86+/////////////////////////////////////////////////////////////////////////////
87+//
88+// DESIGNINFO
89+//
90+
91+#ifdef APSTUDIO_INVOKED
92+GUIDELINES DESIGNINFO DISCARDABLE
93+BEGIN
94+ IDD_CONFIG_DIALOGEX, DIALOG
95+ BEGIN
96+ LEFTMARGIN, 7
97+ RIGHTMARGIN, 213
98+ VERTGUIDE, 14
99+ VERTGUIDE, 53
100+ VERTGUIDE, 55
101+ VERTGUIDE, 115
102+ VERTGUIDE, 120
103+ VERTGUIDE, 207
104+ TOPMARGIN, 7
105+ BOTTOMMARGIN, 270
106+ HORZGUIDE, 21
107+ HORZGUIDE, 35
108+ HORZGUIDE, 41
109+ HORZGUIDE, 55
110+ HORZGUIDE, 65
111+ HORZGUIDE, 74
112+ HORZGUIDE, 86
113+ HORZGUIDE, 99
114+ HORZGUIDE, 105
115+ HORZGUIDE, 119
116+ HORZGUIDE, 125
117+ HORZGUIDE, 139
118+ HORZGUIDE, 170
119+ HORZGUIDE, 184
120+ HORZGUIDE, 190
121+ HORZGUIDE, 204
122+ HORZGUIDE, 210
123+ HORZGUIDE, 224
124+ HORZGUIDE, 252
125+ HORZGUIDE, 268
126+ END
127+END
128+#endif // APSTUDIO_INVOKED
129+
130+
131+#ifndef _MAC
132+/////////////////////////////////////////////////////////////////////////////
133+//
134+// Version
135+//
136+
137+VS_VERSION_INFO VERSIONINFO
138+ FILEVERSION 0,0,0,2
139+ PRODUCTVERSION 0,0,0,2
140+ FILEFLAGSMASK 0x3fL
141+#ifdef _DEBUG
142+ FILEFLAGS 0x1L
143+#else
144+ FILEFLAGS 0x0L
145+#endif
146+ FILEOS 0x40004L
147+ FILETYPE 0x2L
148+ FILESUBTYPE 0x0L
149+BEGIN
150+ BLOCK "StringFileInfo"
151+ BEGIN
152+ BLOCK "041104b0"
153+ BEGIN
154+ VALUE "Comments", "YamabikoClient plugin for Yggdrasil-System based on foobar2000 SDK 0.8.3\0"
155+ VALUE "CompanyName", "Yossie-pon Oniichan\0"
156+ VALUE "FileDescription", "YamabikoClient plugin for Yggdrasil-System based on foobar2000 SDK 0.8.3\0"
157+ VALUE "FileVersion", "0, 0, 0, 2\0"
158+ VALUE "InternalName", "foo_yggd\0"
159+ VALUE "LegalCopyright", "Copyright (C) 2006 Yossie-pon Oniichan, All Rights Reserved.\0"
160+ VALUE "LegalTrademarks", "YamabikoClient for foobar2000\0"
161+ VALUE "OriginalFilename", "foo_yggd.dll\0"
162+ VALUE "PrivateBuild", "\0"
163+ VALUE "ProductName", "foo_yggd.dll for foobar2000 component plugin\0"
164+ VALUE "ProductVersion", "0, 0, 0, 2\0"
165+ VALUE "SpecialBuild", "\0"
166+ END
167+ END
168+ BLOCK "VarFileInfo"
169+ BEGIN
170+ VALUE "Translation", 0x411, 1200
171+ END
172+END
173+
174+#endif // !_MAC
175+
176+#endif // 日本語 resources
177+/////////////////////////////////////////////////////////////////////////////
178+
179+
180+
181+#ifndef APSTUDIO_INVOKED
182+/////////////////////////////////////////////////////////////////////////////
183+//
184+// Generated from the TEXTINCLUDE 3 resource.
185+//
186+
187+
188+/////////////////////////////////////////////////////////////////////////////
189+#endif // not APSTUDIO_INVOKED
190+
--- /dev/null
+++ b/foo_yggd/resource.h
@@ -0,0 +1,26 @@
1+//{{NO_DEPENDENCIES}}
2+// Microsoft Developer Studio generated include file.
3+// Used by foo_yggd.rc
4+//
5+#define IDD_CONFIG_DIALOGEX 101
6+#define IDC_USERNAME 1000
7+#define IDC_PASSWORD 1001
8+#define IDC_VERSION_INFO 1002
9+#define IDC_PLUGIN_DESC 1003
10+#define IDC_YAMABIKO_INTERVAL_1ST 1004
11+#define IDC_PROXY_SERVER 1005
12+#define IDC_PROXY_PORT 1006
13+#define IDC_YAMABIKO_ENABLED 1007
14+#define IDC_YAMABIKO_INTERVAL_2ND 1008
15+#define IDC_PROXY_ENABLED 1009
16+
17+// Next default values for new objects
18+//
19+#ifdef APSTUDIO_INVOKED
20+#ifndef APSTUDIO_READONLY_SYMBOLS
21+#define _APS_NEXT_RESOURCE_VALUE 102
22+#define _APS_NEXT_COMMAND_VALUE 40001
23+#define _APS_NEXT_CONTROL_VALUE 1010
24+#define _APS_NEXT_SYMED_VALUE 101
25+#endif
26+#endif