📄 channel.cpp
字号:
ChanHit *ChanHitList::addHit(ChanHit &h){ int i;
// dont add our own hits
if (servMgr->sessionID.isSame(h.sessionID))
return NULL;
lastHitTime = sys->getTime(); h.time = lastHitTime; for(i=0; i<MAX_HITS; i++)
{
ChanHit &ch = hits[i];
if ((ch.rhost[0].ip == h.rhost[0].ip) && (ch.rhost[0].port == h.rhost[0].port)) if (((ch.rhost[1].ip == h.rhost[1].ip) && (ch.rhost[1].port == h.rhost[1].port)) || (!ch.rhost[1].isValid()))
{ hits[i] = h; return &hits[i]; }
} for(i=0; i<MAX_HITS; i++) if (hits[i].host.ip == 0) {
hits[i] = h; return &hits[i]; } return NULL;}// -----------------------------------int ChanHitList::clearDeadHits(unsigned int timeout, bool clearTrackers){ int cnt=0; unsigned int ctime = sys->getTime(); for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip) {
if (((ctime-hits[i].time) > timeout) && (clearTrackers || (!clearTrackers & !hits[i].tracker)))
deadHit(hits[i]);
else
cnt++; } return cnt;}// -----------------------------------void ChanHitList::deadHit(ChanHit &h){ for(int i=0; i<MAX_HITS; i++) if (hits[i].rhost[0].isSame(h.rhost[0]) && hits[i].rhost[1].isSame(h.rhost[1]))
{ hits[i].init();
}}// -----------------------------------int ChanHitList::numHits(){ int cnt=0; for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip)
cnt++; return cnt;}
// -----------------------------------int ChanHitList::numListeners(){ int cnt=0; for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip) cnt += hits[i].numListeners; return cnt;}// -----------------------------------
int ChanHitList::numTrackers()
{
int cnt=0;
for(int i=0; i<MAX_HITS; i++)
if ((hits[i].host.ip) && (hits[i].tracker))
cnt++;
return cnt;
}
// -----------------------------------int ChanHitList::numBusy(){ int cnt=0; for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip)
cnt += hits[i].busy?1:0; return cnt;}// -----------------------------------int ChanHitList::numStable(){ int cnt=0; for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip)
cnt += hits[i].stable?1:0; return cnt;}// -----------------------------------int ChanHitList::numFirewalled(){ int cnt=0; for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip)
cnt += hits[i].firewalled?1:0; return cnt;}// -----------------------------------int ChanHitList::closestHit(){ int hop=10000; for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip) if (hits[i].hops < hop) hop = hits[i].hops; return hop;}// -----------------------------------int ChanHitList::furthestHit(){ int hop=0; for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip) if (hits[i].hops > hop) hop = hits[i].hops; return hop;}// -----------------------------------unsigned int ChanHitList::newestHit(){ unsigned int time=0; for(int i=0; i<MAX_HITS; i++) if (hits[i].host.ip) if (hits[i].time > time) time = hits[i].time; return time;}// -----------------------------------ChanHit ChanHitList::getHit(Host *sh, unsigned int wait, bool useFirewalled, bool trackersOnly, bool useBusy){
ChanHit best,*bestP=NULL;
best.init();
best.hops = 255;
unsigned int ctime = sys->getTime();
for(int i=0; i<MAX_HITS; i++) { ChanHit *c = &hits[i]; if (c->host.ip)
{
if ((wait==0) || ((ctime-c->lastContact) >= wait))
if ((!c->busy || (c->busy && useBusy)) && (c->hops<best.hops))
{
if (trackersOnly && c->tracker)
{
if (sh)
{
if ((c->rhost[0].ip == sh->ip) && c->rhost[1].isValid())
{
bestP = c;
best = *c;
best.host = best.rhost[1]; // use lan ip
}
}else if ((c->firewalled == useFirewalled) && (servMgr->serverHost.ip!=c->rhost[0].ip))
{
bestP = c;
best = *c;
best.host = best.rhost[0]; // use wan ip
}
}else if (!trackersOnly && !c->tracker)
{ if (sh)
{
if ((c->rhost[0].ip == sh->ip) && c->rhost[1].isValid())
{
bestP = c;
best = *c;
best.host = best.rhost[1]; // use lan ip
}
}else if ((c->firewalled == useFirewalled) && (servMgr->serverHost.ip!=c->rhost[0].ip))
{
bestP = c;
best = *c;
best.host = best.rhost[0]; // use wan ip
}
}
}
} }
if (bestP && wait)
{
bestP->lastContact = ctime;
}
return best;}// -----------------------------------const char *ChanInfo::getTypeStr(TYPE t){ switch (t) { case T_RAW: return "RAW"; case T_MP3: return "MP3"; case T_OGG: return "OGG"; case T_WMA: return "WMA"; case T_MOV: return "MOV"; case T_MPG: return "MPG"; case T_NSV: return "NSV"; case T_WMV: return "WMV"; case T_PLS: return "PLS"; case T_ASX: return "ASX"; default: return "UNKNOWN"; }}// -----------------------------------const char *ChanInfo::getProtocolStr(PROTOCOL t){ switch (t) { case SP_PEERCAST: return "PEERCAST"; case SP_HTTP: return "HTTP"; case SP_FILE: return "FILE"; case SP_MMS: return "MMS"; case SP_PCP: return "PCP";
default: return "UNKNOWN"; }}// -----------------------------------ChanInfo::PROTOCOL ChanInfo::getProtocolFromStr(const char *str){ if (stricmp(str,"PEERCAST")==0) return SP_PEERCAST; else if (stricmp(str,"HTTP")==0) return SP_HTTP; else if (stricmp(str,"FILE")==0) return SP_FILE; else if (stricmp(str,"MMS")==0) return SP_MMS; else if (stricmp(str,"PCP")==0)
return SP_PCP;
else return SP_UNKNOWN;}// -----------------------------------const char *ChanInfo::getTypeExt(TYPE t){ switch(t) { case ChanInfo::T_OGG: return ".ogg"; case ChanInfo::T_MP3: return ".mp3"; case ChanInfo::T_MOV: return ".mov"; case ChanInfo::T_NSV: return ".nsv"; case ChanInfo::T_WMV: return ".wmv"; case ChanInfo::T_WMA: return ".wma"; default: return ""; }}// -----------------------------------ChanInfo::TYPE ChanInfo::getTypeFromStr(const char *str){ if (stricmp(str,"MP3")==0) return T_MP3; else if (stricmp(str,"OGG")==0) return T_OGG; else if (stricmp(str,"RAW")==0) return T_RAW; else if (stricmp(str,"NSV")==0) return T_NSV; else if (stricmp(str,"WMA")==0) return T_WMA; else if (stricmp(str,"WMV")==0) return T_WMV; else if (stricmp(str,"PLS")==0) return T_PLS; else if (stricmp(str,"M3U")==0) return T_PLS; else if (stricmp(str,"ASX")==0) return T_ASX; else return T_UNKNOWN;}// -----------------------------------
bool ChanInfo::matchNameID(ChanInfo &inf)
{
if (inf.id.isSet())
if (id.isSame(inf.id))
return true;
if (!inf.name.isEmpty())
if (name.contains(inf.name))
return true;
return false;
}
// -----------------------------------bool ChanInfo::match(ChanInfo &inf){ bool matchAny=true; if (inf.status != S_UNKNOWN) { if (status != inf.status) return false; } if (inf.bitrate != 0) { if (bitrate == inf.bitrate) return true; matchAny = false; } if (inf.id.isSet()) { if (id.isSame(inf.id)) return true; matchAny = false; } if (inf.contentType != T_UNKNOWN) { if (contentType == inf.contentType) return true; matchAny = false; } if (!inf.name.isEmpty()) { if (name.contains(inf.name)) return true; matchAny = false; } if (!inf.genre.isEmpty()) { if (genre.contains(inf.genre)) return true; matchAny = false; } return matchAny;}// -----------------------------------
bool TrackInfo::update(TrackInfo &inf)
{
bool changed = false;
if (!contact.isSame(inf.contact))
{
contact = inf.contact;
changed = true;
}
if (!title.isSame(inf.title))
{
title = inf.title;
changed = true;
}
if (!artist.isSame(inf.artist))
{
artist = inf.artist;
changed = true;
}
if (!album.isSame(inf.album))
{
album = inf.album;
changed = true;
}
if (!genre.isSame(inf.genre))
{
genre = inf.genre;
changed = true;
}
return changed;
}
// -----------------------------------bool ChanInfo::update(ChanInfo &info){ bool changed = false;
// check valid id
if (!info.id.isSet())
return false;
// only update from chaninfo that has full name etc.. if (info.name.isEmpty()) return false;
// check valid broadcaster key
if (bcID.isSet())
if (!bcID.isSame(info.bcID))
{
LOG_ERROR("ChanInfo BC key not valid");
return false;
}
bcID = info.bcID;
if (bitrate != info.bitrate)
{
bitrate = info.bitrate;
changed = true;
}
if (contentType != info.contentType)
{
contentType = info.contentType;
changed = true;
}
if (!name.isSame(info.name))
{
name = info.name;
changed = true;
}
if (!comment.isSame(info.comment))
{
comment = info.comment;
changed = true;
}
if (!genre.isSame(info.genre))
{
genre = info.genre;
changed = true;
}
if (!url.isSame(info.url))
{
url = info.url;
changed = true;
}
if (track.update(info.track))
changed = true;
return changed;}// -----------------------------------void ChanInfo::initNameID(const char *n){ init(); id.fromStr(n); if (!id.isSet()) name.set(n);}// -----------------------------------void ChanInfo::init(){ status = S_UNKNOWN; name.clear(); bitrate = 0; contentType = T_UNKNOWN; srcProtocol = SP_UNKNOWN; id.clear(); url.clear(); genre.clear(); comment.clear(); track.clear(); lastPlayTime = 0; numSkips = 0;
bcID.clear();
}// -----------------------------------void ChanInfo::readTrackXML(XML::Node *n){ track.clear(); readXMLString(track.title,n,"title"); readXMLString(track.contact,n,"contact"); readXMLString(track.artist,n,"artist"); readXMLString(track.album,n,"album"); readXMLString(track.genre,n,"genre");}// -----------------------------------unsigned int ChanInfo::getUptime(){ // calculate uptime and cap if requested by settings. unsigned int upt; upt = lastPlayTime?(sys->getTime()-lastPlayTime):0; if (chanMgr->maxUptime) if (upt > chanMgr->maxUptime) upt = chanMgr->maxUptime; return upt;}
// ------------------------------------------
void ChanInfo::readTrackAtoms(AtomStream &atom,int numc)
{
for(int i=0; i<numc; i++)
{
int c,d;
ID4 id = atom.read(c,d);
if (id == PCP_CHAN_TRACK_TITLE)
{
atom.readString(track.title.data,sizeof(track.title.data),d);
}else if (id == PCP_CHAN_TRACK_CREATOR)
{
atom.readString(track.artist.data,sizeof(track.artist.data),d);
}else if (id == PCP_CHAN_TRACK_URL)
{
atom.readString(track.contact.data,sizeof(track.contact.data),d);
}else if (id == PCP_CHAN_TRACK_ALBUM)
{
atom.readString(track.album.data,sizeof(track.album.data),d);
}else
atom.skip(c,d);
}
}
// ------------------------------------------
void ChanInfo::readInfoAtoms(AtomStream &atom,int numc)
{
for(int i=0; i<numc; i++)
{
int c,d;
ID4 id = atom.read(c,d);
if (id == PCP_CHAN_INFO_NAME)
{
atom.readString(name.data,sizeof(name.data),d);
}else if (id == PCP_CHAN_INFO_BITRATE)
{
bitrate = atom.readInt();
}else if (id == PCP_CHAN_INFO_GENRE)
{
atom.readString(genre.data,sizeof(genre.data),d);
}else if (id == PCP_CHAN_INFO_URL)
{
atom.readString(url.data,sizeof(url.data),d);
}else if (id == PCP_CHAN_INFO_DESC)
{
atom.readString(desc.data,sizeof(desc.data),d);
}else if (id == PCP_CHAN_INFO_COMMENT)
{
atom.readString(comment.data,sizeof(comment.data),d);
}else if (id == PCP_CHAN_INFO_TYPE)
{
char type[16];
atom.readString(type,sizeof(type),d);
contentType = ChanInfo::getTypeFromStr(type);
}else
atom.skip(c,d);
}
}
// -----------------------------------
void ChanInfo::writeInfoAtoms(AtomStream &atom)
{
atom.writeParent(PCP_CHAN_INFO,7);
atom.writeString(PCP_CHAN_INFO_NAME,name.cstr());
atom.writeInt(PCP_CHAN_INFO_BITRATE,bitrate);
atom.writeString(PCP_CHAN_INFO_GENRE,genre.cstr());
atom.writeString(PCP_CHAN_INFO_URL,url.cstr());
atom.writeString(PCP_CHAN_INFO_DESC,desc.cstr());
atom.writeString(PCP_CHAN_INFO_COMMENT,comment.cstr());
atom.writeString(PCP_CHAN_INFO_TYPE,getTypeStr(contentType));
}
// -----------------------------------
void ChanInfo::writeTrackAtoms(AtomStream &atom)
{
atom.writeParent(PCP_CHAN_TRACK,4);
atom.writeString(PCP_CHAN_TRACK_TITLE,track.title.cstr());
atom.writeString(PCP_CHAN_TRACK_CREATOR,track.artist.cstr());
atom.writeString(PCP_CHAN_TRACK_URL,track.contact.cstr());
atom.writeString(PCP_CHAN_TRACK_ALBUM,track.album.cstr());
}
// -----------------------------------XML::Node *ChanInfo::createChannelXML(){ char idStr[64];
Stri
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -