package com.planet_ink.coffee_mud.Libraries;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.interfaces.BoundedObject.BoundedCube;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.CMSecurity.DbgFlag;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.ChannelsLibrary.CMChannel;
import com.planet_ink.coffee_mud.Libraries.interfaces.ChannelsLibrary.ChannelFlag;
import com.planet_ink.coffee_mud.Libraries.interfaces.ChannelsLibrary.ChannelMsg;
import com.planet_ink.coffee_mud.Libraries.interfaces.ColorLibrary.Color;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;
import java.util.*;
/*
Copyright 2005-2016 Bo Zimmerman
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
public class CMChannels extends StdLibrary implements ChannelsLibrary
{
@Override public String ID(){return "CMChannels";}
public final int QUEUE_SIZE=100;
public String[] baseChannelNames= new String[0];
public List<CMChannel> channelList = new Vector<CMChannel>();
protected Language commonLang = null;
public final static List<ChannelMsg> emptyQueue=new ReadOnlyList<ChannelMsg>(new Vector<ChannelMsg>(1));
public final static Set<ChannelFlag> emptyFlags=new ReadOnlySet<ChannelFlag>(new HashSet<ChannelFlag>(1));
@Override
public int getNumChannels()
{
return channelList.size();
}
@Override
public CMChannel getChannel(int channelNumber)
{
if((channelNumber>=0)&&(channelNumber<channelList.size()))
return channelList.get(channelNumber);
return null;
}
public CMChannel createNewChannel(final String name)
{
return createNewChannel(name, "", "", "", new HashSet<ChannelFlag>(), "", "");
}
public CMChannel createNewChannel(final String name, final String mask, final Set<ChannelFlag> flags,
final String colorOverrideANSI, final String colorOverrideWords)
{
return createNewChannel(name, "", "", mask, flags, colorOverrideANSI, colorOverrideWords);
}
@Override
public CMChannel createNewChannel(final String name, final String i3Name, final String imc2Name,
final String mask, final Set<ChannelFlag> flags,
final String colorOverrideANSI, final String colorOverrideWords)
{
final SLinkedList<ChannelMsg> queue = new SLinkedList<ChannelMsg>();
return new CMChannel()
{
@Override
public String name()
{
return name;
}
@Override
public String i3name()
{
return i3Name;
}
@Override
public String imc2Name()
{
return imc2Name;
}
@Override
public String mask()
{
return mask;
}
@Override
public String colorOverrideANSICodes()
{
return colorOverrideANSI;
}
@Override
public String colorOverrideWords()
{
return colorOverrideWords;
}
@Override
public Set<ChannelFlag> flags()
{
return flags;
}
@Override
public SLinkedList<ChannelMsg> queue()
{
return queue;
}
};
}
@Override
public List<ChannelMsg> getChannelQue(int channelNumber, int numNewToSkip, int numToReturn)
{
if((channelNumber>=0)&&(channelNumber<channelList.size()))
{
final CMChannel channel = channelList.get(channelNumber);
LinkedList<ChannelMsg> msgs=new LinkedList<ChannelMsg>();
if(numNewToSkip < channel.queue().size())
{
int skipNum=numNewToSkip;
for(ChannelMsg msg : channel.queue())
{
if((--skipNum < 0)&&(msgs.size() < numToReturn))
msgs.addFirst(msg);
}
}
if(msgs.size()>=numToReturn)
return msgs;
if(channel.flags().contains(ChannelsLibrary.ChannelFlag.NOBACKLOG))
return msgs;
final List<Pair<String,Long>> backLog=CMLib.database().getBackLogEntries(channel.name(), numNewToSkip, numToReturn);
if(backLog.size()<=msgs.size())
return msgs;
final List<ChannelMsg> allMsgs = new XVector<ChannelMsg>();
for(int x=0;x<backLog.size()-msgs.size();x++)
{
final CMMsg msg=CMClass.getMsg();
msg.parseFlatString(backLog.get(x).first);
final long time = backLog.get(x).second.longValue();
allMsgs.add(new ChannelMsg()
{
@Override
public CMMsg msg()
{
return msg;
}
@Override
public long sentTimeMillis()
{
return time;
}
});
}
allMsgs.addAll(msgs);
return allMsgs;
}
return emptyQueue;
}
@Override
public boolean mayReadThisChannel(MOB sender, boolean areaReq, MOB M, int channelNumber)
{
return mayReadThisChannel(sender,areaReq,M,channelNumber,false);
}
@Override
public boolean mayReadThisChannel(MOB sender,
boolean areaReq,
MOB M,
int channelNumber,
boolean offlineOK)
{
if((sender==null)||(M==null))
return false;
final PlayerStats pstats=M.playerStats();
if(pstats==null)
return false;
final Room R=M.location();
if(((!offlineOK))
&&((M.amDead())||(R==null)))
return false;
final CMChannel chan=getChannel(channelNumber);
if(chan==null)
return false;
if(chan.flags().contains(ChannelFlag.CLANONLY)||chan.flags().contains(ChannelFlag.CLANALLYONLY))
{
// only way to fail an all-clan send is to have NO clan.
if(!CMLib.clans().checkClanPrivilege(M, Clan.Function.CHANNEL))
return false;
if((!CMLib.clans().isAnyCommonClan(sender,M))
&&((!chan.flags().contains(ChannelFlag.CLANALLYONLY))
||(!CMLib.clans().findAnyClanRelations(M,sender,Clan.REL_ALLY))))
return false;
}
if((!pstats.getIgnored().contains(sender.Name()))
&&(CMLib.masking().maskCheck(chan.mask(),M,true))
&&((!areaReq)
||(sender.location()==null)
||(R==null)
||(R.getArea()==sender.location().getArea()))
&&(!CMath.isSet(pstats.getChannelMask(),channelNumber)))
return true;
return false;
}
@Override
public boolean mayReadThisChannel(MOB sender, boolean areaReq, Session ses, int channelNumber)
{
if(ses==null)
return false;
final MOB M=ses.mob();
if((sender==null)
||(M==null)
||(M.amDead())
||(M.location()==null))
return false;
final PlayerStats pstats=M.playerStats();
if(pstats==null)
return false;
String senderName=sender.Name();
final int x=senderName.indexOf('@');
if(x>0)
senderName=senderName.substring(0,x);
final CMChannel chan=getChannel(channelNumber);
if(chan==null)
return false;
if(chan.flags().contains(ChannelFlag.CLANONLY)||chan.flags().contains(ChannelFlag.CLANALLYONLY))
{
// only way to fail an all-clan send is to have NO clan.
if(!CMLib.clans().checkClanPrivilege(M, Clan.Function.CHANNEL))
return false;
if((!CMLib.clans().isAnyCommonClan(sender,M))
&&((!chan.flags().contains(ChannelFlag.CLANALLYONLY))
||(!CMLib.clans().findAnyClanRelations(M,sender,Clan.REL_ALLY))))
return false;
}
final Room R=M.location();
if((!ses.isStopped())
&&(R!=null)
&&(!pstats.getIgnored().contains(senderName))
&&(CMLib.masking().maskCheck(chan.mask(),M,true))
&&((!areaReq)
||(sender.location()==null)
||(R.getArea()==sender.location().getArea()))
&&(!CMath.isSet(pstats.getChannelMask(),channelNumber)))
return true;
return false;
}
@Override
public boolean mayReadThisChannel(MOB M, int channelNumber, boolean zapCheckOnly)
{
if(M==null)
return false;
if(channelNumber>=getNumChannels())
return false;
final CMChannel chan=getChannel(channelNumber);
if(chan==null)
return false;
if((chan.flags().contains(ChannelFlag.CLANONLY)||chan.flags().contains(ChannelFlag.CLANALLYONLY))
&&(!CMLib.clans().checkClanPrivilege(M, Clan.Function.CHANNEL)))
return false;
if(((zapCheckOnly)||((!M.amDead())&&(M.location()!=null)))
&&(CMLib.masking().maskCheck(chan.mask(),M,true))
&&(!CMath.isSet(M.playerStats().getChannelMask(),channelNumber)))
return true;
return false;
}
@Override
public void channelQueUp(final int channelNumber, final CMMsg msg)
{
CMLib.map().sendGlobalMessage(msg.source(),CMMsg.TYP_CHANNEL,msg);
final CMChannel channel=getChannel(channelNumber);
final SLinkedList<ChannelMsg> q=channel.queue();
synchronized(q)
{
if(q.size()>=QUEUE_SIZE)
q.removeLast();
final long now = System.currentTimeMillis();
q.addFirst(new ChannelMsg()
{
@Override
public CMMsg msg()
{
return msg;
}
@Override
public long sentTimeMillis()
{
return now;
}
});
}
if((!channel.flags().contains(ChannelsLibrary.ChannelFlag.NOBACKLOG))
&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.CHANNELBACKLOGS))
&&(!CMProps.getVar(CMProps.Str.CHANNELBACKLOG).equals("0")))
CMLib.database().addBackLogEntry(getChannel(channelNumber).name(), msg.toFlatString());
}
@Override
public int getChannelIndex(String channelName)
{
channelName=channelName.toUpperCase();
for(int c=0;c<channelList.size();c++)
{
if((channelList.get(c)).name().equals(channelName))
return c;
}
for(int c=0;c<channelList.size();c++)
{
if((channelList.get(c)).name().startsWith(channelName))
return c;
}
return -1;
}
@Override
public int getChannelCodeNumber(String channelName)
{
channelName=channelName.toUpperCase();
for(int c=0;c<channelList.size();c++)
{
if((channelList.get(c)).name().equals(channelName))
return 1<<c;
}
for(int c=0;c<channelList.size();c++)
{
if((channelList.get(c)).name().startsWith(channelName))
return 1<<c;
}
return -1;
}
@Override
public String findChannelName(String channelName)
{
channelName=channelName.toUpperCase();
for(int c=0;c<channelList.size();c++)
{
if((channelList.get(c)).name().equals(channelName))
return (channelList.get(c)).name().toUpperCase();
}
for(int c=0;c<channelList.size();c++)
{
if((channelList.get(c)).name().startsWith(channelName))
return (channelList.get(c)).name().toUpperCase();
}
return "";
}
@Override
public List<String> getFlaggedChannelNames(ChannelFlag flag)
{
final List<String> channels=new Vector<String>();
for(int c=0;c<channelList.size();c++)
{
if(channelList.get(c).flags().contains(flag))
channels.add(channelList.get(c).name().toUpperCase());
}
return channels;
}
@Override
public String getExtraChannelDesc(String channelName)
{
final StringBuilder str=new StringBuilder("");
final int dex = getChannelIndex(channelName);
if(dex >= 0)
{
final CMChannel chan=getChannel(dex);
final Set<ChannelFlag> flags = chan.flags();
final String mask = chan.mask();
if(flags.contains(ChannelFlag.CLANALLYONLY))
str.append(L(" This is a channel for clans and their allies."));
if(flags.contains(ChannelFlag.CLANONLY))
str.append(L(" Only members of the same clan can see messages on this channel."));
if(flags.contains(ChannelFlag.PLAYERREADONLY)||flags.contains(ChannelFlag.READONLY))
str.append(L(" This channel is read-only."));
if(flags.contains(ChannelFlag.SAMEAREA))
str.append(L(" Only people in the same area can see messages on this channel."));
if((mask!=null)&&(mask.trim().length()>0))
str.append(L(" The following may read this channel : @x1",CMLib.masking().maskDesc(mask)));
}
return str.toString();
}
private void clearChannels()
{
channelList=new Vector<CMChannel>();
}
@Override
public List<CMChannel> getIMC2ChannelsList()
{
final List<CMChannel> list=new Vector<CMChannel>();
for(int i=0;i<channelList.size();i++)
{
if((channelList.get(i).imc2Name()!=null)
&&(channelList.get(i).imc2Name().length()>0))
list.add(channelList.get(i));
}
return list;
}
@Override
public List<CMChannel> getI3ChannelsList()
{
final List<CMChannel> list=new Vector<CMChannel>();
for(int i=0;i<channelList.size();i++)
{
if((channelList.get(i).i3name()!=null)
&&(channelList.get(i).i3name().length()>0))
list.add(channelList.get(i));
}
return list;
}
@Override
public String[] getChannelNames()
{
return baseChannelNames;
}
@Override
public List<Session> clearInvalidSnoopers(Session mySession, int channelCode)
{
List<Session> invalid=null;
if(mySession!=null)
{
for(final Session S : CMLib.sessions().allIterable())
{
if((S!=mySession)
&&(S.mob()!=null)
&&(mySession.isBeingSnoopedBy(S))
&&(!mayReadThisChannel(S.mob(),channelCode,false)))
{
if(invalid==null)
invalid=new Vector<Session>();
invalid.add(S);
mySession.setBeingSnoopedBy(S,false);
}
}
}
return invalid;
}
@Override
public void restoreInvalidSnoopers(Session mySession, List<Session> invalid)
{
if((mySession==null)||(invalid==null))
return;
for(int s=0;s<invalid.size();s++)
mySession.setBeingSnoopedBy(invalid.get(s), true);
}
public String parseOutFlags(String mask, Set<ChannelFlag> flags, String[] colorOverride)
{
final List<String> V=CMParms.parseSpaces(mask,true);
for(int v=V.size()-1;v>=0;v--)
{
final String s=V.get(v).toUpperCase();
if(CMParms.contains(CMParms.toStringArray(ChannelFlag.values()), s))
{
V.remove(v);
flags.add(ChannelFlag.valueOf(s));
}
else
{
Color C=(Color)CMath.s_valueOf(Color.class, s);
if(C!=null)
{
V.remove(v);
if(s.startsWith("BG"))
colorOverride[0]=colorOverride[0]+C.getANSICode();
else
colorOverride[0]=C.getANSICode()+colorOverride[0];
colorOverride[1]+=" "+s;
}
}
}
final StringBuilder str=new StringBuilder();
for(final String s : V)
str.append(s).append(" ");
return str.toString().trim();
}
@Override
public int loadChannels(String list, String ilist, String imc2list)
{
clearChannels();
while(list.length()>0)
{
int x=list.indexOf(',');
String item=null;
if(x<0)
{
item=list.trim();
list="";
}
else
{
item=list.substring(0,x).trim();
list=list.substring(x+1);
}
x=item.indexOf(' ');
final CMChannel chan;
if(x>0)
{
final String[] colorOverride=new String[]{"",""};
final Set<ChannelFlag> flags = new HashSet<ChannelFlag>();
String mask=parseOutFlags(item.substring(x+1).trim(),flags,colorOverride);
item=item.substring(0,x);
chan = this.createNewChannel(item.toUpperCase().trim(), mask, flags, colorOverride[0], colorOverride[1]);
}
else
chan = this.createNewChannel(item.toUpperCase().trim());
channelList.add(chan);
}
while(ilist.length()>0)
{
final int x=ilist.indexOf(',');
String item=null;
if(x<0)
{
item=ilist.trim();
ilist="";
}
else
{
item=ilist.substring(0,x).trim();
ilist=ilist.substring(x+1);
}
final int y1=item.indexOf(' ');
final int y2=item.lastIndexOf(' ');
if((y1<0)||(y2<=y1))
continue;
final String lvl=item.substring(y1+1,y2).trim();
final String ichan=item.substring(y2+1).trim();
item=item.substring(0,y1);
final Set<ChannelFlag> flags = new HashSet<ChannelFlag>();
String nameStr=item.toUpperCase().trim();
final String[] colorOverride=new String[]{"",""};
String maskStr=parseOutFlags(lvl,flags,colorOverride);
String i3nameStr=ichan;
final CMChannel chan = this.createNewChannel(nameStr, i3nameStr, "", maskStr, flags, colorOverride[0], colorOverride[1]);
channelList.add(chan);
}
while(imc2list.length()>0)
{
final int x=imc2list.indexOf(',');
String item=null;
if(x<0)
{
item=imc2list.trim();
imc2list="";
}
else
{
item=imc2list.substring(0,x).trim();
imc2list=imc2list.substring(x+1);
}
final int y1=item.indexOf(' ');
final int y2=item.lastIndexOf(' ');
if((y1<0)||(y2<=y1))
continue;
final Set<ChannelFlag> flags = new HashSet<ChannelFlag>();
final String lvl=item.substring(y1+1,y2).trim();
final String ichan=item.substring(y2+1).trim();
item=item.substring(0,y1);
String nameStr=item.toUpperCase().trim();
final String[] colorOverride=new String[]{"",""};
String maskStr=parseOutFlags(lvl,flags,colorOverride);
String imc2Name=ichan;
final CMChannel chan = this.createNewChannel(nameStr, "", imc2Name, maskStr, flags, colorOverride[0], colorOverride[1]);
channelList.add(chan);
}
baseChannelNames=new String[channelList.size()];
for(int i=0;i<channelList.size();i++)
baseChannelNames[i]=channelList.get(i).name();
if(!CMSecurity.isDisabled(CMSecurity.DisFlag.CHANNELAUCTION))
{
channelList.add(this.createNewChannel("AUCTION"));
}
return channelList.size();
}
@Override
public boolean sendChannelCMMsgTo(Session ses, boolean areareq, int channelInt, CMMsg msg, MOB sender)
{
final MOB M=ses.mob();
if(M==null)
return false;
final Room R=M.location();
boolean didIt=false;
if(mayReadThisChannel(sender,areareq,ses,channelInt)
&&(R!=null)
&&((sender.location()==R)||(R.okMessage(ses.mob(),msg))))
{
if(ses.getClientTelnetMode(Session.TELNET_GMCP))
{
ses.sendGMCPEvent("comm.channel", "{\"chan\":\""+getChannel(channelInt).name()+"\",\"msg\":\""+
MiniJSON.toJSONString(CMLib.coffeeFilter().fullOutFilter(null, M, msg.source(), msg.target(), msg.tool(), CMStrings.removeColors((M==msg.source())?msg.sourceMessage():msg.othersMessage()), false))
+"\",\"player\":\""+msg.source().name()+"\"}");
}
M.executeMsg(M,msg);
didIt=true;
if(msg.trailerMsgs()!=null)
{
for(final CMMsg msg2 : msg.trailerMsgs())
{
if((msg!=msg2)&&(R.okMessage(M,msg2)))
M.executeMsg(M,msg2);
}
msg.trailerMsgs().clear();
}
}
return didIt;
}
@Override
public void createAndSendChannelMessage(MOB mob, String channelName, String message, boolean systemMsg)
{
final int channelInt=getChannelIndex(channelName);
if(channelInt<0)
return;
final PlayerStats pStats=mob.playerStats();
message=CMProps.applyINIFilter(message,CMProps.Str.CHANNELFILTER);
final CMChannel chan=getChannel(channelInt);
final Set<ChannelFlag> flags=chan.flags();
channelName=chan.name();
final String channelColor="^Q";
CMMsg msg=null;
if(systemMsg)
{
String str="["+channelName+"] '"+message+"'^</CHANNEL^>^?^.";
if((!mob.name().startsWith("^"))||(mob.name().length()>2))
str="<S-NAME> "+str;
msg=CMClass.getMsg(mob,null,null,
CMMsg.MASK_CHANNEL|CMMsg.MASK_ALWAYS|CMMsg.MSG_SPEAK,channelColor+"^<CHANNEL \""+channelName+"\"^>"+str,
CMMsg.NO_EFFECT,null,
CMMsg.MASK_CHANNEL|(CMMsg.TYP_CHANNEL+channelInt),channelColor+"^<CHANNEL \""+channelName+"\"^>"+str);
}
else
if(message.startsWith(",")
||(message.startsWith(":")
&&(message.length()>1)
&&(Character.isLetter(message.charAt(1))||message.charAt(1)==' ')))
{
String msgstr=message.substring(1);
final Vector<String> V=CMParms.parse(msgstr);
Social S=CMLib.socials().fetchSocial(V,true,false);
if(S==null)
S=CMLib.socials().fetchSocial(V,false,false);
if(S!=null)
msg=S.makeChannelMsg(mob,channelInt,channelName,V,false);
else
{
msgstr=CMProps.applyINIFilter(msgstr,CMProps.Str.EMOTEFILTER);
if(msgstr.trim().startsWith("'")||msgstr.trim().startsWith("`"))
msgstr=msgstr.trim();
else
msgstr=" "+msgstr.trim();
final String srcstr="^<CHANNEL \""+channelName+"\"^>["+channelName+"] "+mob.name()+msgstr+"^</CHANNEL^>^N^.";
final String reststr="^<CHANNEL \""+channelName+"\"^>["+channelName+"] <S-NAME>"+msgstr+"^</CHANNEL^>^N^.";
msg=CMClass.getMsg(mob,null,null,
CMMsg.MASK_CHANNEL|CMMsg.MASK_ALWAYS|CMMsg.MSG_SPEAK,channelColor+""+srcstr,
CMMsg.NO_EFFECT,null,
CMMsg.MASK_CHANNEL|(CMMsg.TYP_CHANNEL+channelInt),channelColor+reststr);
}
}
else
{
msg=CMClass.getMsg(mob,null,null,
CMMsg.MASK_CHANNEL|CMMsg.MASK_ALWAYS|CMMsg.MSG_SPEAK,L("@x1^<CHANNEL \"@x2\"^>You @x3 '@x4'^</CHANNEL^>^N^.",channelColor,channelName,channelName,message),
CMMsg.NO_EFFECT,null,
CMMsg.MASK_CHANNEL|(CMMsg.TYP_CHANNEL+channelInt),L("@x1^<CHANNEL \"@x2\"^><S-NAME> @x3S '@x4'^</CHANNEL^>^N^.",channelColor,channelName,channelName,message));
}
if((chan.flags().contains(ChannelsLibrary.ChannelFlag.ACCOUNTOOC)
||(chan.flags().contains(ChannelsLibrary.ChannelFlag.ACCOUNTOOCNOADMIN) && (!CMSecurity.isStaff(mob))))
&&(pStats!=null)
&&(pStats.getAccount()!=null)
&&(msg.source()==mob))
{
final String accountName=pStats.getAccount().getAccountName();
if(msg.sourceMessage()!=null)
msg.setSourceMessage(CMStrings.replaceAll(msg.sourceMessage(), "<S-NAME>", accountName));
if(msg.targetMessage()!=null)
msg.setTargetMessage(CMStrings.replaceAll(msg.targetMessage(), "<S-NAME>", accountName));
if(msg.othersMessage()!=null)
msg.setOthersMessage(CMStrings.replaceAll(msg.othersMessage(), "<S-NAME>", accountName));
}
if(chan.flags().contains(ChannelsLibrary.ChannelFlag.NOLANGUAGE))
msg.setTool(getCommonLanguage());
final Room R=mob.location();
CMLib.commands().monitorGlobalMessage(R, msg);
if((R!=null)
&&((!R.isInhabitant(mob))||(R.okMessage(mob,msg))))
{
final boolean areareq=flags.contains(ChannelsLibrary.ChannelFlag.SAMEAREA);
channelQueUp(channelInt,msg);
for(final Session S : CMLib.sessions().localOnlineIterable())
sendChannelCMMsgTo(S,areareq,channelInt,msg,mob);
}
if((CMLib.intermud().i3online()&&(CMLib.intermud().isI3channel(channelName)))
||(CMLib.intermud().imc2online()&&(CMLib.intermud().isIMC2channel(channelName))))
CMLib.intermud().i3channel(mob,channelName,message);
}
protected Language getCommonLanguage()
{
if(commonLang==null)
{
commonLang = (Language)CMClass.getAbility("Common");
}
return commonLang;
}
@Override
public boolean activate()
{
if(serviceClient==null)
{
name="THChannels"+Thread.currentThread().getThreadGroup().getName().charAt(0);
serviceClient=CMLib.threads().startTickDown(this, Tickable.TICKID_SUPPORT|Tickable.TICKID_SOLITARYMASK, MudHost.TIME_UTILTHREAD_SLEEP, 1);
}
return true;
}
@Override
public boolean tick(Tickable ticking, int tickID)
{
try
{
if(!CMSecurity.isDisabled(CMSecurity.DisFlag.UTILITHREAD))
{
tickStatus=Tickable.STATUS_ALIVE;
try
{
final String propStr=CMProps.getVar(CMProps.Str.CHANNELBACKLOG).toUpperCase().trim();
if((!CMSecurity.isDisabled(CMSecurity.DisFlag.CHANNELBACKLOGS))
&&(!propStr.equalsIgnoreCase("INFINITY"))
&&(!propStr.equalsIgnoreCase("FOREVER")))
{
if(CMath.isInteger(propStr))
CMLib.database().trimBackLogEntries(getChannelNames(), CMath.s_int(propStr), 0);
else
{
String[] ss=propStr.split(" ");
if((ss.length!=2)&&(!CMath.isInteger(ss[0])))
Log.errOut("CMChannels","Malformed CHANNELBACKLOG entry in coffeemud.ini file: "+propStr);
else
if(ss[1].equals("DAYS")||ss[1].equals("DAY"))
CMLib.database().trimBackLogEntries(getChannelNames(), Integer.MAX_VALUE, System.currentTimeMillis() - (CMath.s_int(ss[0]) * TimeManager.MILI_DAY));
else
if(ss[1].equals("WEEKS")||ss[1].equals("WEEK"))
CMLib.database().trimBackLogEntries(getChannelNames(), Integer.MAX_VALUE, System.currentTimeMillis() - (CMath.s_int(ss[0]) * TimeManager.MILI_WEEK));
else
if(ss[1].equals("MONTHS")||ss[1].equals("MONTHS"))
CMLib.database().trimBackLogEntries(getChannelNames(), Integer.MAX_VALUE, System.currentTimeMillis() - (CMath.s_int(ss[0]) * TimeManager.MILI_MONTH));
else
if(ss[1].equals("YEARSS")||ss[1].equals("YEAR"))
CMLib.database().trimBackLogEntries(getChannelNames(), Integer.MAX_VALUE, System.currentTimeMillis() - (CMath.s_int(ss[0]) * TimeManager.MILI_YEAR));
else
Log.errOut("CMChannels","Malformed CHANNELBACKLOG entry in coffeemud.ini file: "+propStr);
}
}
}
finally
{
}
}
}
finally
{
tickStatus=Tickable.STATUS_NOT;
setThreadStatus(serviceClient,"sleeping");
}
return true;
}
@Override
public boolean shutdown()
{
clearChannels();
if(CMLib.threads().isTicking(this, TICKID_SUPPORT|Tickable.TICKID_SOLITARYMASK))
{
CMLib.threads().deleteTick(this, TICKID_SUPPORT|Tickable.TICKID_SOLITARYMASK);
serviceClient=null;
}
return true;
}
}