WSH Panel mod - Scriptbeispiele (Seekbar, Rating, Album-Rating, Coverart & mehr)

Begonnen von TomPro, 16. Juni 2009, 19:24:54

Vorheriges Thema - Nächstes Thema

tedgo

Na, dann evaluiere den Codec in on_paint:

var codec = fb.TitleFormat("%codec%");
var g_img;

function on_paint(gr) {
    if (fb.IsPlaying || fb.IsPaused) g_img = gdi.Image(fb.FoobarPath + "icons\\" + codec.Eval() + ".png");
    else g_img = gdi.Image(fb.FoobarPath + "icons\\generic.png");
    g_img && gr.DrawImage(g_img, 100,10, 128, 128, 0, 0, g_img.Width, g_img.Height);
}

grimes

Super! Folgender code in on_paint reicht doch:


g_img && gr.DrawImage(g_img, 100,10, 128, 128, 0, 0, g_img.Width, g_img.Height);


codec-Variablen Definition kann bleiben, wo sie ist.
Ist übrigens nach meiner Meinung "dirty code" in on_paint Variablen zu evaluieren. Dort sollten nur die Zeichnungselemente stehen (wie der Name schon sagt).

Jetzt wird bei unbekannten (kein Bild vorhanden) Codec nichts angezeigt und der Script-error passiert nicht mehr.

tedgo for president. :crazy:

tedgo

Zitat von: grimes in 27. Februar 2010, 13:42:38
Ist übrigens nach meiner Meinung "dirty code" in on_paint Variablen zu evaluieren. Dort sollten nur die Zeichnungselemente stehen (wie der Name schon sagt).
Außerhalb einer Funktion ist es hingegen sinnlos, da es dann nur bei der Initiierung des Panels evaluiert wird ;).
Deshalb entweder in on_paint() oder meinetwegen auch - wie du es ja zusätzlich hast - in on_playback_new_track()

grimes

Meiner Meinung nach sollte die Variablenevaluation immer in der Aktion (Callback) stehen, niemals in on_paint, weil on_paint ja bei allen möglichen Aktionen aufgerufen wird und bei den meisten Aktionen ist es unnötig eine spezielle Variable zu evaluieren.
Zusätzlich sollte man auch zur Initiierung des Panels die Variable evaluieren. Die Initiierung ist ja streng genommen auch eine Aktion, die eine Variablenevaluation nötig macht.

grimes

Ich habe die History-Skripte überarbeitet und, da sie alle sehr ähnlich sind, in eine Version zusammengepackt.

History

Skript besteht aus folgenden Varianten:


  • Playlist History
  • Album History
  • Artist History
  • Performer History
  • Composer History
  • Genre History
  • Track Title History

Die Variante kann durch rechtsklick in WSH-Panel | Properties gewählt werden.


//history by grimes
//fb2k 1.0+, WSH Panel Mod 1.3.2+ required
//DUI/CUI ready

function RGB(r, g, b) {
    return (0xff000000 | (r << 16) | (g << 8) | (b));
}

var dui = window.InstanceType;
var g_font = dui === 1 ? window.GetFontDUI(0) : window.GetFontCUI(0);
//var color = RGB(200,0,0);
var color = dui === 1 ? window.GetColorDUI(2) : RGB(200, 0, 0);
//var color2 = RGB(0,0,0);
var color2 = dui === 1 ? window.GetColorDUI(0) : window.GetColorCUI(0);

var tagcount = 0;
var tagname;
var sum = 0;

var proc = 100;

var writtentoconsole = false;

var itemplayed = window.GetProperty("show only items played >1min", false);
var historysize = window.GetProperty("history size", 22);
var displayeditems = window.GetProperty("displayed items", 22);

var tagchoice1 = window.GetProperty("playlist history", true);
if (tagchoice1) {
    var tag = fb.GetPlaylistName(fb.ActivePlaylist);
    tagname = "Playlist";
}
var tagchoice2 = window.GetProperty("album history", false);
if (tagchoice2) {
    var tag = "%album%";
    tagname = "Album";
}
var tagchoice3 = window.GetProperty("artist history", false);
if (tagchoice3) {
    var tag = "%artist%";
    tagname = "Artist";
}
var tagchoice4 = window.GetProperty("genre history", false);
if (tagchoice4) {
    var tag = "%genre%";
    tagname = "Genre";
}
var tagchoice5 = window.GetProperty("performer history", false);
if (tagchoice5) {
    var tag = "%performer%";
    tagname = "Performer";
}
var tagchoice6 = window.GetProperty("track title history", false);
if (tagchoice6) {
    var tag = "%track% %title%";
    tagname = "Track Title";
}
var tagchoice7 = window.GetProperty("composer history", false);
if (tagchoice7) {
    var tag = "%composer%";
    tagname = "Composer";
}

if (tagchoice1) {
    var activetag = new Array(tag);
    tagcount = 1;
    sum = 1;
} else {
    var activetag = new Array();
}
activetag.reverse();

if ((fb.IsPlaying || fb.IsPaused) && (!tagchoice1) && (!itemplayed)) {
    activetag.unshift(fb.TitleFormat(tag).Eval());
    tagcount = 1;
    sum = 1;
}
var datestamp = new Array(Date());
datestamp.reverse();

var equaltag = 1;
var equaltagarray = new Array();
equaltagarray.reverse();

var totalstring = new Array();

//global Variables for text field
var DT_TOP = 0x00000000;
var DT_LEFT = 0x00000000;
var DT_CENTER = 0x00000001;
var DT_RIGHT = 0x00000002;
var DT_VCENTER = 0x00000004;
var DT_BOTTOM = 0x00000008;
var DT_WORDBREAK = 0x00000010;
var DT_SINGLELINE = 0x00000020;
var DT_EXPANDTABS = 0x00000040;
var DT_TABSTOP = 0x00000080;
var DT_NOCLIP = 0x00000100;
var DT_EXTERNALLEADING = 0x00000200;
var DT_CALCRECT = 0x00000400;
var DT_NOPREFIX = 0x00000800;
var DT_INTERNAL = 0x00001000;
var DT_EDITCONTROL = 0x00002000;
var DT_PATH_ELLIPSIS = 0x00004000;
var DT_END_ELLIPSIS = 0x00008000;
var DT_MODIFYSTRING = 0x00010000;
var DT_RTLREADING = 0x00020000;
var DT_WORD_ELLIPSIS = 0x00040000;
var DT_NOFULLWIDTHCHARBREAK = 0x00080000;
var DT_HIDEPREFIX = 0x00100000;
var DT_PREFIXONLY = 0x00200000;

function on_paint(gr) {
    gr.FillSolidRect(0, 0, window.Width, window.Height, dui == 1 ? window.GetColorDUI(1) : window.GetColorCUI(3));
    if (itemplayed && (!tagchoice1)) {
        gr.GdiDrawText(tagname + " History (items: " + tagcount + "/" + sum + " [" + proc + "%]) items played", g_font, color2, 5, 5, window.Width, window.Height, DT_TOP | DT_LEFT | DT_SINGLELINE);
    }
    else {
        gr.GdiDrawText(tagname + " History (items: " + tagcount + "/" + sum + " [" + proc + "%])", g_font, color2, 5, 5, window.Width, window.Height, DT_TOP | DT_LEFT | DT_SINGLELINE);
    }
    if (writtentoconsole) {
        gr.GdiDrawText("written to console", g_font, color2, 300, 5, window.Width, window.Height, DT_TOP | DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS);
    }
    for (i = 0; i < activetag.length; i++) {
        if (i === 0) {
            gr.GdiDrawText(i + ". " + activetag[i] + " (" + equaltag + ") [" + datestamp[i] + "]", g_font, color, 5, i * 16 + 25, window.Width - 10, window.Height, DT_TOP | DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS);
        } else if (i < displayeditems) {
            gr.GdiDrawText(i + ". " + activetag[i] + " (" + equaltagarray[i - 1] + ") [" + datestamp[i] + "]", g_font, color2, 5, i * 16 + 25, window.Width - 10, window.Height, DT_TOP | DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_END_ELLIPSIS);
        }
    }
}

function content() {
    tagcount++;
    sum++;
    procent();
    unshift();
    equaltag = 1;
    pop();
}

function unshift() {
    if (tagchoice1) {
        activetag.unshift(fb.GetPlaylistName(fb.ActivePlaylist));
    } else {
        activetag.unshift(fb.TitleFormat(tag).Eval());
    }
    datestamp.unshift(Date());
    equaltagarray.unshift(equaltag);
}

function pop() {
    if (tagcount >= historysize + 1) {
        activetag.pop();
        datestamp.pop();
        equaltagarray.pop();
    }
}

function procent() {
    proc = (tagcount / sum * 100);
    proc = Math.round(proc * 100) / 100;
}

function on_playback_new_track() {
    if (fb.TitleFormat(tag).Eval() !== activetag[0] && fb.TitleFormat(tag).Eval() !== "" && (!tagchoice1) && (!itemplayed)) {
        content();
    } else if (fb.TitleFormat(tag).Eval() === activetag[0] && fb.TitleFormat(tag).Eval() !== "" && (!tagchoice1) && (!itemplayed)) {
        equaltag++;
        sum++;
        procent();
    }
    writtentoconsole = false;
    window.Repaint();
}

function on_playlist_switch() {
    if (tagchoice1) {
        tagcount++;
        sum++;
        procent();
        unshift();
        equaltag = 1;
        pop();
        writtentoconsole = false;
        window.Repaint();
    }
}

function on_item_played() {
    if (fb.TitleFormat(tag).Eval() !== activetag[0] && fb.TitleFormat(tag).Eval() !== "" && (!tagchoice1) && (itemplayed)) {
        content();
    } else if (fb.TitleFormat(tag).Eval() === activetag[0] && fb.TitleFormat(tag).Eval() !== "" && (!tagchoice1) && (itemplayed)) {
        equaltag++;
        sum++;
        proc();
    }
    writtentoconsole = false;
    window.Repaint();
}

function on_playback_stop() {
    writtentoconsole = false;
    window.Repaint();
}

function on_mouse_lbtn_down() {
    totalstring.splice(0,totalstring.length);
    for (i = 0; i < activetag.length; i++) {
        if (i === 0) {
            totalstring.unshift(i + ". " + activetag[i] + " (" + equaltag + ") [" + datestamp[i] + "]");
        } else if (i < displayeditems) {
            totalstring .unshift(i + ". " + activetag[i] + " (" + equaltagarray[i - 1] + ") [" + datestamp[i] + "]");
        }
    }
    totalstring.reverse();
    fb.trace(totalstring.join("\n"));
    writtentoconsole = true;
    window.Repaint();
}

function on_colors_changed() {
    color2 = dui === 1 ? window.GetColorDUI(0) : window.GetColorCUI(0);
    window.Repaint();
}

function on_font_changed() {
    g_font = dui === 1 ? window.GetFontDUI(0) : window.GetFontCUI(0);
    window.Repaint();
}


Diese Version ersetzt natürlich alle vorher geposteten Versionen.


Spirit_of_the_ocean

Ich muss mich bedanken  :top: Der Tipp hat geholfen. Ich hatte aus verschiedenen Sachen den Code zusammengebastelt. Ich habs ungefähr verstanden wie es in etwa funktioniert. Allerdings wollte ich den Code noch einmal neu sortieren (beser gesagt ausmisten) und mit Kommentaren versehen.

Hier könnt ihr den Zwischenstand sehen:

Fehlerhafter Link entfernt - tedgo

Spirit_of_the_ocean

Nochmal eine Frage:

Wie bekomme ich es hin, in Jscript zu prüfen, ob eine Zahl in einem bestimmten Zahlenbereich liegt? Hintergrund ist, dass ich ein Bildanzeigen lassen will in Abhängigkeit vom Playcountbereich.
Nur was gibt es dafür für einen Befehl:
Wie drücke ich aus, wenn der Playcount zwischen zwanzig und 49 liegt....

tedgo

Vielleicht gibts ja 'ne elegantere Lösung aber ich habe das so (ähnlich) in meinem Script gelöst:
var playcount = fb.TitleFormat("%play_count%").Eval();
if (playcount >= 20 && playcount < 50) {Code was dann ausgeführt werden soll}
else if (playcount >= 50 && playcount < 80) {Code was dann ausgeführt werden soll}
usw.

Andre69

Zitat von: Spirit_of_the_ocean in 01. März 2010, 20:06:38
Nochmal eine Frage:

Wie bekomme ich es hin, in Jscript zu prüfen, ob eine Zahl in einem bestimmten Zahlenbereich liegt? Hintergrund ist, dass ich ein Bildanzeigen lassen will in Abhängigkeit vom Playcountbereich.
Nur was gibt es dafür für einen Befehl:
Wie drücke ich aus, wenn der Playcount zwischen zwanzig und 49 liegt....
Du kannst auch ABSTEIGEND prüfen und dann immer wieder eine Variable überschreiben.
z.b.:
function on_playback_new_track(metadb) {
var playcount = fb.TitleFormat("$if2(%play_count%,0)").Eval();
        var text = "über 50";
if(playcount < 50) text = "unter 50";
if(playcount < 40) text = "unter 40";
if(playcount < 30) text = "unter 30";
if(playcount < 20) text = "unter 20";
if(playcount < 10) text = "unter 10";
fb.trace(text);
}

TomPro

Zitat von: Andre69 in 21. Februar 2010, 16:51:05
Ja, Deutsche Anleitung währe was gutes. Da ist aber ein WIKI besser geeignet.
Zum Thema CreateImage eine kleine Spielerei:

// ==PREPROCESSOR==
// @import "%fb2k_path%scripts\Flags.txt"
// ==/PREPROCESSOR==

function RGB(r, g, b) {
    return (0xff000000 | (r << 16) | (g << 8) | (b));
}
font = gdi.Font("Consolas", 107);
bmp = gdi.CreateImage(800,100);
tgr = bmp.GetGraphics();
tgr.GdiDrawText("Andre",font,RGB(55,55,255),0,0,bmp.width,bmp.height, DT_LEFT);
bmp2 = bmp.Clone(0, 0, bmp.Width, bmp.Height);
bmp2.RotateFlip(6);
maske = gdi.Image(fb.FoobarPath + "images\\maske.png");
mask = maske.Resize(bmp2.Width, bmp2.Height);
bmp2.ApplyMask(mask);

function on_paint(gr) {
gr.DrawImage(bmp,10,10,bmp.width,bmp.height,0,0,bmp.width,bmp.height,0,255);
gr.DrawImage(bmp2,10,10+bmp.height,bmp2.width,bmp2.height,0,0,bmp2.width,bmp2.height,0,255);
}





Danke das hat geholfen jetzt kann mein Infofenster weitergehen, geht übrigens in die Richtung was Spirit_of_the_ocean plant.

grimes

Ich habe wieder alle Farbenskripte zu einem Skript zusammengefasst. Alle bisherigen Versionen werden gelöscht.

Color

bestehend aus den Varianten:

  • playcount
  • rating
  • year
  • length





Farbverlauf:
rot selten, schlecht, alt, kurz
gelb
grün
cyan
blau
violett oft, gut, neu, lang

http://www.color-security.de/html/spektral_rgb.html



//color by grimes
//fb2k 1.0+, WSH Panel Mod 1.3.2+ required
//DUI/CUI ready

function RGB(r, g, b) {
    return (0xff000000 | (r << 16) | (g << 8) | (b));
}

var g_font = gdi.Font("Segoe UI", 12, 0);
var dui = window.InstanceType;

var x = 255;
var y = 255;
var z = 255;
var tag = "";
var tag2 = "";
var playcount = window.GetProperty("playcount", true);
var rating = window.GetProperty("rating", false);
var year = window.GetProperty("year", false);
var length = window.GetProperty("length [s]", false);


if (fb.IsPlaying || fb.IsPaused) {
    get_tag_value();
    calculate_color();
}

function on_paint(gr) {
    gr.FillSolidRect(0, 0, window.Width, window.Height, RGB(x, y, z));
    if (playcount) {
        gr.DrawString("playcount " + tag2, g_font, RGB(0, 0, 0), 0, 0, window.Width, window.Height, 0x11005000);
    } else if (rating) {
        gr.DrawString("rating " + tag, g_font, RGB(0, 0, 0), 0, 0, window.Width, window.Height, 0x11005000);
    } else if (year) {
        gr.DrawString("year " + tag2, g_font, RGB(0, 0, 0), 0, 0, window.Width, window.Height, 0x11005000);
    } else if (length) {
        gr.DrawString("length " + fb.TitleFormat("%length%").Eval(), g_font, RGB(0, 0, 0), 0, 0, window.Width, window.Height, 0x11005000);
    }
}

function playcount_ratio() {
    //tag = tag2; //experienced user
    //tag = tag2 * 5; //intermediate user
    tag = tag2 * 10; //novice user
}

function get_tag_value() {
    if (playcount) {
        tag2 = fb.TitleFormat("%play_count%").Eval();
        playcount_ratio();
    } else if (rating) {
        tag = fb.TitleFormat("%rating%").Eval();
        tag = parseInt(tag);
    } else if (year) {
        tag2 = fb.TitleFormat("%date%").Eval();
        tag = (tag2 - 1950) * 2;
    } else if (length) {
        tag2 = fb.TitleFormat("%length_seconds%").Eval();
        tag = tag2 / 10
    }
}

function calculate_color() {
    if (rating) {
        x = tag < 2 || tag > 4 ? 255 : 0;
        y = tag > 0 && tag < 4 ? 255 : 0;
        z = tag > 2 ? 255 : 0;
    } else {
        if (tag <= 25) {
            x = 255;
            y = tag * 10;
            z = 0;
        } else if (tag > 25 && tag <= 50) {
            x = 255 - (tag - 25) * 10;
            y = 255;
            z = 0;
        } else if (tag > 50 && tag <= 75) {
            x = 0;
            y = 255;
            z = (tag - 50) * 10;
        } else if (tag > 75 && tag <= 100) {
            x = 0;
            y = 255 - (tag - 75) * 10;
            z = 255;
        } else if (tag > 100 && tag <= 125) {
            x = (tag - 100) * 10;
            y = 0;
            z = 255;
        } else if (tag > 125) {
            x = 255;
            y = 0;
            z = 255;
        } else {
            x = 255;
            y = 0;
            z = 0;
        }
    }
}

function on_playback_new_track() {
    get_tag_value();
    calculate_color();
    window.Repaint();
}

function on_playback_stop() {
    x = 255;
    y = 255;
    z = 255;
    tag = "";
    tag2 = "";
    window.Repaint();
}

function on_item_played() {
    if (playcount) {
        tag2++
        playcount_ratio();
        calculate_color();
        window.Repaint();
    }
}

function on_colors_changed() {
    window.Repaint();
}

function on_font_changed() {
    window.Repaint();
}




Andre69

Statistik (Grundsystem).

Als erstes möchte ich die NACHTEILE aufzählen:

  • Um neue Tracks hinzuzufügen müssen diese einmal kurz angespielt werden.
  • Es kann der Titel nur vom aktuell Spielenden Track geändert werden. Album und Artist sollte nie geändert werden.
  • Dateiname oder Pfad dürfen nie geändert werden.
  • Beim anspielen gibt es eine kleine verzögerung wegen Datenbankzugriff
  • Nach einer Minute gibt es eine kleine verzögerung wegen Datenbankzugriff

Am besten Editiert man die Tags so wie man sie haben will vor dem hinzufügen.

Ich habe versucht eine Datenbank mit Windowsmitteln - also Jetdatenbank zu erstellen. Das hat nicht geklappt. Aber zum glück gibt es noch das Schlanke SQlite. SQlite hat auch eine ähnliche SQL Syntax, so brauchte ich nur Kleinigkeiten ändern. SQlite ist auch schnell und einfach und unkompliziert installierbar. Am schnellsten Funktioniert aber MySQL. Es ist ja auch ein Server der als Dienst gestartet wird. Braucht daher aber auch eine umfangreiche Installation. Am besten noch mit Apache und PHPMyADMIN. Ich habe hier gleich ein ganzes XAMP System Installiert.

Was bekommt ihr hier ?

Eine Datenbank die eine Spielstatistik speichert. Man kann Statistiken nach Artist, Alben oder Tracks erstellen. Es ist da noch lange nicht alles ausgereizt.
Ich werde hier ERSTMAL nur das GRUNDSYSTEM zum Download bieten. Das Grundsystem zeigt den Rang des Tracks, Album und Artisten an. Platz 1 ist der an meisten gespielte Track.
Es wird Angezeigt wann der Track das letzte mal gespielt wurde. Welches der momentane Lieblingstracks ist. Dieser wird dadurch ermittelt das es am meisten in der vergangenen Woche gespielt wurde.
Dann folgt eine Gesammtstatistik der gespielten Tracks.
Installationsanweisung für SQlite und MySQL ist im Paket (Anhang).

Viel Spass beim Datensammeln.

grimes

Meine Variante von Andre69's (ersten) Statistic-Skript.



Zur Anwendung: Das Skript ist alltagstauglich. Je nach Komplexität kann die SQL-Query bis zu 2sec dauern, ist aber in der Praxis nicht störend. Die Datenbankabfrage geschieht nur, wenn das Panel geöffnet ist. Bei Trackstart und nach 1min (Datenbankzugriff) habe ich keine nachteiligen Effekte bemerkt. Die Möglichkeiten der statistischen Auswertung sind längst nicht ausgeschöpft und werden lediglich durch mangelnde SQL-Kenntnisse beschränkt.

Fazit: Sehr empfehlenswert. Ich möchte Andre69's Skript nicht mehr missen.


Andre69

Ein Script welches anzeigt was die Freunde in Last.fm hören/gehört haben.
Es muss geändert werde:
user = Last.fm Username
key = api key (kann man von last.fm bekommen, oder man sucht einwenig... )
friends = die Namen der Freunde die man "beobachten" will. Müssen als Array eingegeben werden z.B.: var friends = new Array("Peter","Petra","paul","dAc00lMan");
friendstimer = das ist das Interval der Abfrage, steht momentan auf 5Minuten (300000)
---

var user = "";
var key = "";
var friendstimer = window.CreateTimerInterval(300000);
var friends = new Array("");
var fartists = new Array();
var ftitles = new Array();
var font = gdi.Font("consolas", 13);
var DT_LEFT = 0x00000000;
var DT_WORD_ELLIPSIS = 0x00040000;
var DT_NOPREFIX = 0x00000800;
var ww = wh = 0;

if (window.InstanceType == 0) {
textcolor = window.GetColorCUI(0);
textcolor_hl = window.GetColorCUI(1);
backcolor = window.GetColorCUI(3);
} else if (window.InstanceType == 1) {
textcolor = window.GetColorDUI(0);
textcolor_hl = window.GetColorDUI(2);
backcolor = window.GetColorDUI(1);
selcolor = window.GetColorDUI(3);
}

function xpathconn(url) {
xml = new ActiveXObject("Msxml2.DOMDocument.6.0");
xml.async = false;
xml.validateOnParse = false;
xml.load(url);
xml.setProperty("SelectionLanguage", "XPath");
return xml;
}

function getFriends() {
var url = "http://ws.audioscrobbler.com/2.0/?method=user.getfriends&user=" + user + "&api_key=" + key + "&recenttracks=true";
xmldoc = xpathconn(url);
try {
for(i = 0; i < friends.length; i++) {
fartists[friends[i]] = xmldoc.selectSingleNode("//lfm/friends/user[name='"+friends[i]+"']/recenttrack/artist/name").text;
ftitles[friends[i]] = xmldoc.selectSingleNode("//lfm/friends/user[name='"+friends[i]+"']/recenttrack/name").text;
}
}
catch(e) {
fb.trace("error: ",e);
}
}

function on_paint(gr) {
gr.FillSolidRect(0,0,ww,wh,backcolor);
var text = "";
for(i = 0; i < friends.length; i++) {
text += friends[i] + "\n";
text += fartists[friends[i]] + " - " + ftitles[friends[i]] + "\n"
}
gr.GdiDrawText(text, font, textcolor, 3, 3, ww - 6, wh - 6, DT_LEFT | DT_WORD_ELLIPSIS | DT_NOPREFIX);
}

function on_size() {
ww = window.width;
wh = window.height;
}

function on_timer(id) {
if (friendstimer && id == friendstimer.ID) {
getFriends();
}
}

getFriends();

tedgo

Wieso nutzt du nicht einfach die Panel Properties für die Eingabe der Optionen? Dann müsste man nicht immer im Script danach suchen und darin rumpfuschen. :)

Beispiel:
var user = window.GetProperty("Username", "");
var key = window.GetProperty("Key", "");

var friends_temp = window.GetProperty("Friends", "");
var friends = friends_temp.split(",");

var g_interval = window.GetProperty("Friendstimer", 300000);
var friendstimer = window.CreateTimerInterval(g_interval);