Biscuit/src/main/java/com/fpghoti/biscuit/guild/BiscuitGuild.java

493 lines
13 KiB
Java

package com.fpghoti.biscuit.guild;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import java.util.Timer;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.PluginCore;
import com.fpghoti.biscuit.audio.AudioScheduler;
import com.fpghoti.biscuit.config.BiscuitConfig;
import com.fpghoti.biscuit.config.BiscuitProperties;
import com.fpghoti.biscuit.logging.BColor;
import com.fpghoti.biscuit.logging.BiscuitLogger;
import com.fpghoti.biscuit.rest.MessageText;
import com.fpghoti.biscuit.rss.YTFeed;
import com.fpghoti.biscuit.rss.YTFeedConfig;
import com.fpghoti.biscuit.timer.BiscuitTimer;
import com.fpghoti.biscuit.timer.task.ChatCountTimer;
import com.fpghoti.biscuit.timer.task.DecrementTimer;
import com.fpghoti.biscuit.timer.task.SoftMuteTimer;
import com.fpghoti.biscuit.user.CaptchaUser;
import com.fpghoti.biscuit.user.PreUser;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Invite;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.User;
public class BiscuitGuild {
public static BiscuitGuild getBiscuitGuild(Guild g) {
for(BiscuitGuild b : Main.getBiscuits()) {
if(b.getGuild().getId().equals(g.getId())) {
return b;
}
}
return null;
}
public static BiscuitGuild getBiscuitGuild(String guildcode) {
for(BiscuitGuild b : Main.getBiscuits()) {
if(b.getProperties().getGuildCode().equalsIgnoreCase(guildcode)) {
return b;
}
}
return null;
}
public static ArrayList<PreUser> getPreUsers(User u) {
ArrayList<PreUser> pres = new ArrayList<PreUser>();
for(Guild g : Main.getJDA().getGuilds()) {
if(g.isMember(u)){
BiscuitGuild b = getBiscuitGuild(g);
if(b.preUserExists(u)) {
pres.add(b.getPreUser(u));
}
}
}
return pres;
}
public static BiscuitGuild loadGuild(Guild g) {
BiscuitGuild biscuit = new BiscuitGuild(Main.getJDA(), g, Main.getLogger());
biscuit.addTimer(new ChatCountTimer(biscuit));
biscuit.addTimer(new SoftMuteTimer(biscuit));
biscuit.addTimer(new DecrementTimer(biscuit));
biscuit.loadTimers();
Main.registerBiscuit(biscuit);
return biscuit;
}
private boolean isMain;
private JDA jda;
private BiscuitLogger logger;
private Timer timer;
private List<BiscuitTimer> timers;
private File captchaDir;
private File ytFeedDir;
//private Cage cage;
private Guild guild;
private HashMap<String, Integer> inviteUses;
private HashMap<String, YTFeedConfig> ytfeeds;
private BiscuitConfig config;
private BiscuitProperties properties;
private GuildMessageStore messageStore;
private AudioPlayer player;
private AudioScheduler scheduler;
private CopyOnWriteArrayList<PreUser> users = new CopyOnWriteArrayList<PreUser>();
private HashMap<Member, Role> rolequeue;
public BiscuitGuild(JDA jda, Guild guild, BiscuitLogger log) {
this.jda = jda;
this.guild = guild;
this.logger = log;
this.isMain = guild == null;
this.messageStore = new GuildMessageStore(this);
this.config = new BiscuitConfig(this);
config.generateConfig();
this.properties = new BiscuitProperties(this);
this.rolequeue = new HashMap<Member, Role>();
this.player = Main.getPlayerManager().createPlayer();
this.ytfeeds = new HashMap<String, YTFeedConfig>();
scheduler = new AudioScheduler(this);
player.addListener(scheduler);
timer = new Timer();
timers = new ArrayList<BiscuitTimer>();
if(!Main.isPlugin) {
captchaDir = new File("captcha");
captchaDir.mkdir();
if(guild != null) {
File f = new File("ytchannels");
f.mkdir();
ytFeedDir = new File(f, guild.getId());
ytFeedDir.mkdir();
}
}else {
captchaDir = new File(PluginCore.plugin.getDataFolder(), "captcha");
captchaDir.mkdir();
if(guild != null) {
ytFeedDir = new File(PluginCore.plugin.getDataFolder(), "ytchannels\\" + guild.getId());
ytFeedDir.mkdirs();
}
}
if(isMain) {
wipeCaptchaDir();
}
if(!isMain) {
loadPreUsers();
inviteUses = new HashMap<String, Integer>();
if(canManageServer() && properties.checkJoinInvite()) {
guild.retrieveInvites().queue((invs) -> {
indexInvites(invs);
});
}
}
if(guild != null) {
loadYoutubeFeeds();
Runnable post = () -> {
try {
log("Updating Youtube feeds...");
postYoutubeFeeds();
} catch (IOException e) {
e.printStackTrace();
}
};
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(post, 0, 1, TimeUnit.MINUTES);
}
}
public BiscuitConfig getConfig() {
return config;
}
public BiscuitProperties getProperties() {
return properties;
}
public GuildMessageStore getMessageStore() {
return messageStore;
}
public Guild getGuild() {
return guild;
}
public boolean canManageServer() {
return guild.getSelfMember().hasPermission(Permission.MANAGE_SERVER);
}
public AudioPlayer getAudioPlayer() {
return player;
}
public AudioScheduler getAudioScheduler() {
return scheduler;
}
public YTFeedConfig loadYouTubeFeedConfig(String alias) {
alias = alias.toLowerCase();
String channelID = "null";
String youTubeChannelURL = "null";
String message = "null";
String lastVideo = "null";
Properties prop = new Properties();
InputStream input = null;
File config = new File(ytFeedDir, alias);
if(!config.exists()) {
logger.error("Could not locate YouTube feed config.");
return null;
}
try {
input = new FileInputStream(config);
prop.load(input);
channelID = prop.getProperty("TextChannelID");
youTubeChannelURL = prop.getProperty("YouTubeChannelURL");
message = prop.getProperty("Message");
lastVideo = prop.getProperty("LastVideo");
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
TextChannel textChannel = jda.getTextChannelById(channelID);
if(textChannel == null) {
logger.error("Error retrieving Text Channel from YouTube feed file.");
return null;
}
YTFeed feed = new YTFeed(alias, textChannel, youTubeChannelURL, message);
feed.setLastVideo(lastVideo);
return new YTFeedConfig(this, feed);
}
public void loadYoutubeFeeds() {
ytfeeds.clear();
File[] files = ytFeedDir.listFiles();
for(File f : files) {
String alias = f.getName().toLowerCase();
ytfeeds.put(alias, loadYouTubeFeedConfig(alias));
}
}
public boolean addYoutubeFeed(String alias, TextChannel channel, String channelURL, String message) {
alias = alias.toLowerCase();
if(guild == null || ytfeeds.containsKey(alias)) {
return false;
}
YTFeed feed = new YTFeed(alias, channel, channelURL, message);
//Generate a file for the feed
new YTFeedConfig(this, feed);
//Loads all feeds from files into hash map
loadYoutubeFeeds();
return true;
}
public void postYoutubeFeeds() throws IOException {
for(String s : ytfeeds.keySet()) {
YTFeedConfig config = ytfeeds.get(s);
YTFeed feed = config.getFeed();
feed.post();
config.setLastPosted(feed.getLastVideo());
}
}
public File getYTFeedDir() {
return ytFeedDir;
}
public void log(String message) {
if(properties == null) {
logger.info(message);
return;
}
logger.info("[" + BColor.CYAN + properties.getGuildCode().toUpperCase() + BColor.RESET + "]: " + message);
}
public void warn(String message) {
if(properties == null) {
logger.warn(message);
return;
}
logger.warn("[" + properties.getGuildCode().toUpperCase() + "]: " + message);
}
public void error(String message) {
if(properties == null) {
logger.error(message);
return;
}
logger.error("[" + properties.getGuildCode().toUpperCase() + "]: " + message);
}
public JDA getJDA() {
return jda;
}
public void say(TextChannel channel, String message) {
MessageText.send(channel, message);
}
public void loadTimers() {
timer.cancel();
timer = new Timer();
for(BiscuitTimer t : timers) {
timer.schedule(t,t.getDelay(), t.getPeriod());
}
}
public void addTimer(BiscuitTimer bt) {
timers.add(bt);
}
public void removeTimer(BiscuitTimer bt) {
timers.remove(bt);
}
public void wipeCaptchaDir() {
log("Wiping captcha files...");
boolean good = true;
File[] files = captchaDir.listFiles();
for (File file : files){
if (!file.delete()){
good = false;
error("Could not remove captcha file: " + file);
}
}
if(good) {
log("All captcha files successfully removed!");
}else {
error("Some captcha file(s) could not be removed!");
}
}
public ArrayList<TextChannel> getCaptchaLogChannels() {
ArrayList<TextChannel> ch = new ArrayList<TextChannel>();
for(TextChannel t : guild.getTextChannels()) {
if(t.getName().equalsIgnoreCase(properties.getEventLogChannel())) {
ch.add(t);
}
}
return ch;
}
public void eventLog(String msg) {
if(properties.logEvents()) {
for(TextChannel t : getCaptchaLogChannels()) {
MessageText.send(t, msg);
}
}
}
public Role getDefaultRole() {
for(Role r : guild.getRoles()) {
if(r.getName().toLowerCase().contains(properties.getDefaultRole().toLowerCase())) {
return r;
}
}
return null;
}
public Role getCaptchaRewardRole() {
for(Role r : guild.getRoles()) {
if(r.getName().toLowerCase().contains(properties.getCaptchaReward().toLowerCase())) {
return r;
}
}
return null;
}
private void loadPreUsers() {
if(!properties.captchaEnabled()) {
return;
}
for(Member m : guild.getMembers()) {
User u = m.getUser();
if(!preUserExists(u)) {
if(m.getRoles().size() == 1) {
for(Role role : m.getRoles()){
if(role.getName().equalsIgnoreCase(properties.getDefaultRole())){
log(BColor.MAGENTA_BOLD + "Adding pre-join check for user " + u.getName() + " (" + u.getAsMention() + ")...");
users.add(PreUser.getPreUser(CaptchaUser.getCaptchaUser(u), this));
}
}
}
}
}
}
private void indexInvites(List<Invite> invs) {
for(Invite i : invs) {
String code = i.getCode();
int uses = i.getUses();
inviteUses.put(code, uses);
}
}
public HashMap<String, Integer> getInviteUses(){
return inviteUses;
}
public void setInviteUses(HashMap<String, Integer> c) {
inviteUses = c;
}
public void clearInviteUses() {
inviteUses.clear();
}
public void addPreUser(PreUser user) {
if(!users.contains(user)) {
users.add(user);
}else {
error("CAPTCHA ERROR: Tried to add PreUser when one already exists");
}
}
public void removePreUser(PreUser user) {
ArrayList<PreUser> temp = new ArrayList<PreUser>(users);
for(PreUser u : temp) {
if(u.getUser().getId().equals(user.getUser().getId())) {
user.setDone();
users.remove(u);
}
}
}
public CopyOnWriteArrayList<PreUser> getPreUsers(){
return users;
}
public PreUser getPreUser(User user) {
for(PreUser u : users) {
if(u.getUser().getId().equals(user.getId())) {
return u;
}
}
return null;
}
public boolean preUserExists(User user) {
return getPreUser(user) != null;
}
public File getConfigDir() {
boolean isMain = guild == null;
if(isMain) {
if(Main.isPlugin) {
PluginCore.plugin.getDataFolder().mkdir();
return PluginCore.plugin.getDataFolder();
}else {
return new File("").getAbsoluteFile();
}
}else {
File dir;
if(!Main.isPlugin) {
dir = new File("guilds");
}else {
dir = new File(PluginCore.plugin.getDataFolder(), "guilds");
}
dir.mkdir();
return dir;
}
}
public HashMap<Member, Role> getRoleQueue() {
return rolequeue;
}
public void remove() {
log("Removing guild biscuit...");
for(BiscuitTimer t : timers) {
t.cancel();
}
for(PreUser p : users) {
p.remove();
}
Main.unregisterBiscuit(this);
}
}