package launcher;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import javax.swing.JOptionPane;
import javax.swing.JLabel;
class Files implements Runnable
{
private final static String SEPARATOR = System.getProperty("file.separator");
/** Local dir where the files will be downloaded */
static String storage_dir = /*System.getProperty("user.dir") + */"temp";
/** Local dir where the downloaded zips will be stored */
static String download_dir = storage_dir + SEPARATOR + "pobierane";
/** Local dir where the unpacked files will be stored */
static String unpack_dir = storage_dir + SEPARATOR + "wypakowane";
/** Local dir where the joined files will be stored */
static String data_dir = storage_dir + SEPARATOR + "data";
private String game_dir;
private JLabel msg;
Files (String gd, JLabel msg)
{
game_dir = gd;
this.msg = msg;
}
public void run()
{
System.out.println("Wypakowuję pliki");
msg.setText("Wypakowuję pliki...");
unzipFiles();
System.out.println("Łączę pliki");
msg.setText("Łączę pliki...");
joinAllFiles();
System.out.println("Tworzę plik PAK");
msg.setText("Tworzę plik PAK...");
createPAK();
System.out.println("Kopiuję PAK do katalogu gry");
msg.setText("Kopiuję PAK do katalogu gry...");
copyPAK();
//unzip("D:\\Gry\\Aion\\l10n\\1_enu\\data\\data.pak", "D:\\testowy");
System.out.println("Usuwam tymczasowe pliki");
msg.setText("Usuwam tymczasowe pliki...");
try {
delete(new File(unpack_dir));
delete(new File(data_dir));
} catch (IOException e) {
e.printStackTrace();
}
createTempDirs();
}
static public void createTempDirs()
{
String[] dirs_to_create = { download_dir, unpack_dir, data_dir };
for (String dir : dirs_to_create)
{
File f = new File(dir);
if (!f.exists()) f.mkdirs();
}
}
public static void joinFiles(String[] files, String output, String main_tag, String encoding)
{
try
{
File o = new File(unpack_dir + SEPARATOR + output);
if (o.exists()) o.delete();
FileWriter output_file = new FileWriter(o);
output_file.write("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\r\n<" + main_tag + ">");
String a;
for (String rfn : files)
{
BufferedReader br = new BufferedReader(new FileReader(unpack_dir + SEPARATOR + rfn));
while ((a = br.readLine()) != null)
{
output_file.write("\r\n" + a);
}
br.close();
}
output_file.write("\r\n</" + main_tag + ">");
output_file.close();
} catch (IOException exc)
{
System.err.println(exc.toString());
}
}
private void joinAllFiles()
{
String[][] filesToJoin = {
{"strings" + SEPARATOR + "client_strings_order.xml", "strings" + SEPARATOR + "client_strings_questy.xml", "strings" + SEPARATOR + "client_strings_quest_items_name.xml", "strings" + SEPARATOR + "client_strings_quest_items_desc.xml", "strings" + SEPARATOR + "client_strings_title_name.xml", "strings" + SEPARATOR + "client_strings_title_desc.xml"},
{"strings" + SEPARATOR + "client_strings_skill_name.xml", "strings" + SEPARATOR + "client_strings_skill_desc.xml"},
{"strings" + SEPARATOR + "client_strings_item_name.xml", "strings" + SEPARATOR + "client_strings_item_desc.xml"},
{"strings" + SEPARATOR + "client_strings_item2_name.xml", "strings" + SEPARATOR + "client_strings_item2_desc.xml"}
};
String[] destFiles = {
"strings" + SEPARATOR + "client_strings_quest.xml",
"strings" + SEPARATOR + "client_strings_skill.xml",
"strings" + SEPARATOR + "client_strings_item.xml",
"strings" + SEPARATOR + "client_strings_item2.xml"
};
String[] destEncodings = {
"utf-16",
"utf-16",
"utf-16",
"utf-16"
};
String[] destTags = {
"strings",
"strings",
"strings",
"strings"
};
for (int i=0; i<filesToJoin.length; ++i)
{
joinFiles(filesToJoin[i], destFiles[i], destTags[i], destEncodings[i]);
for (String f : filesToJoin[i])
{
System.err.println("Usuwam plik: " + f);
if (!new File(unpack_dir + SEPARATOR + f).delete()) System.err.println("Nie można usunąć pliku: " + f);
}
}
}
private void createPAK()
{
//zipMultiRecursively(new File(unpack_dir).list(), data_dir + SEPARATOR + "data.pak");
try {
zipDir(data_dir + SEPARATOR + "data.zip", unpack_dir);
} catch (Exception e) {
e.printStackTrace();
}
}
static public int isFileUpdated (URL url, File local)
{
try {
long local_length = 0;
if (local.exists()) local_length = local.length();
long url_length = url.openConnection().getContentLength();
if (url_length == 162) url_length = 0;
System.out.println("Sprawdzam: -- LOCAL: " + String.valueOf(local_length) + " --- URL: " + String.valueOf(url_length) + " -- LOCAL: " + local.getPath() + ", URL: " + url.getPath());
if (local_length == url_length) return 1; else return 0;
} catch (IOException e) {
e.printStackTrace();
}
return -1;
}
private void copyPAK()
{
String destPath = game_dir + SEPARATOR + "l10n" + SEPARATOR + "1_enu" + SEPARATOR + "data";
String data = getRealPath(destPath);
if (data == "") {
try {
java.nio.file.Files.createDirectories(new File(destPath).toPath());
data = destPath;
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Tworzę potrzebne foldery w katalogu gry -- " + data);
}
if (new File(data).exists())
{
try {
if (!java.nio.file.Files.move(
new File(data_dir + SEPARATOR + "data.zip").toPath(),
new File(data + SEPARATOR + "data.pak").toPath(),
java.nio.file.StandardCopyOption.REPLACE_EXISTING).toFile().exists())
JOptionPane.showMessageDialog(null, "Nie można skopiować paczki do folderu: " + data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String getRealPath(String pathToCheck)
{
StringBuffer path = new StringBuffer();
String[] pathSlices = pathToCheck.split("@" + SEPARATOR + "@");
for (String dir : pathSlices)
{
File currentDir = new File(dir);
// Folder istnieje, dodaj go do ścieżki
if (currentDir.exists())
path.append(currentDir + SEPARATOR);
// Folder nie istnieje, sprawdź, czy jest pod inną nazwą
else
{
if (path.length() == 0) return "";
String[] currentPathFiles = new File(path.toString()).list();
for (String c : currentPathFiles)
{
if (c.toLowerCase() == dir.toLowerCase())
{
path.append(c + SEPARATOR);
break;
}
}
}
}
return path.toString();
}
static public ArrayList<String> getFilesToDownload(ArrayList<String> server_files)
{
ArrayList<String> filestodownload = new ArrayList<String>();
String fn;
for (String sv : server_files)
{
fn = sv.substring(sv.lastIndexOf('/') + 1);
try {
int updated = isFileUpdated(new URL(sv), new File(download_dir + SEPARATOR + fn));
if (updated == 0)
{
System.out.println("Muszę pobrać: -- LOCAL: " + fn + " --- URL: " + sv);
filestodownload.add(sv);
}
else if (updated == -1)
{
JOptionPane.showMessageDialog(null, "Plik: " + fn + " nie może zostać pobrany. Zgłoś to do kogoś z IronSquadu!");
return new ArrayList<String>();
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
return filestodownload;
}
@SuppressWarnings("rawtypes")
private static void unzip(String strZipFile, String strDest) {
try
{
File fSourceZip = new File(strZipFile);
String zipPath = strDest;
//System.out.println(zipPath + " created");
ZipFile zipFile = new ZipFile(fSourceZip);
Enumeration e = zipFile.entries();
while(e.hasMoreElements())
{
ZipEntry entry = (ZipEntry)e.nextElement();
File destinationFilePath = new File(zipPath,entry.getName());
//create directories if required.
destinationFilePath.getParentFile().mkdirs();
//if the entry is directory, leave it. Otherwise extract it.
if(entry.isDirectory())
{
continue;
}
else
{
//System.out.println("Extracting " + destinationFilePath);
/*
* Get the InputStream for current entry
* of the zip file using
*
* InputStream getInputStream(Entry entry) method.
*/
BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
int b;
byte buffer[] = new byte[1024];
/*
* read the current entry from the zip file, extract it
* and write the extracted file.
*/
FileOutputStream fos = new FileOutputStream(destinationFilePath);
BufferedOutputStream bos = new BufferedOutputStream(fos, 1024);
while ((b = bis.read(buffer, 0, 1024)) != -1)
{
bos.write(buffer, 0, b);
}
//flush the output stream and close it.
bos.flush();
bos.close();
//close the input stream.
bis.close();
}
}
zipFile.close();
}
catch(IOException ioe)
{
System.out.println("IOError :" + ioe + " -- IN FILE: " + strZipFile);
}
}
private void unzipFiles()
{
String[] files_to_unzip = new File(download_dir).list();
for (String file : files_to_unzip)
{
unzip(download_dir + SEPARATOR + file, unpack_dir);
}
}
public static void delete(File f) throws IOException {
if (f.isDirectory()) {
for (File c : f.listFiles())
delete(c);
}
if (!f.delete())
throw new FileNotFoundException("Failed to delete file: " + f);
}
private static void zipDir(String zipFileName, String dir) throws Exception {
File dirObj = new File(dir);
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
System.out.println("Creating : " + zipFileName);
addDir(dirObj, out);
out.close();
}
static void addDir(File dirObj, ZipOutputStream out) throws IOException {
File[] files = dirObj.listFiles();
byte[] tmpBuf = new byte[1024];
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
addDir(files[i], out);
continue;
}
String fap = files[i].getAbsolutePath();
String rel_path = fap.substring(fap.indexOf("wypakowane") + 11).replace("\\", "/");
FileInputStream in = new FileInputStream(fap);
System.out.println(" Adding: " + rel_path);
out.putNextEntry(new ZipEntry(rel_path));
int len;
while ((len = in.read(tmpBuf)) > 0) {
out.write(tmpBuf, 0, len);
}
out.closeEntry();
in.close();
}
}
static void zipMultiRecursively(String[] sourceDir, String zipFile)
{
try
{
//create object of FileOutputStream
FileOutputStream fout = new FileOutputStream(zipFile);
//create object of ZipOutputStream from FileOutputStream
ZipOutputStream zout = new ZipOutputStream(fout);
//create File object from source directory
for (int i=0; i<sourceDir.length; ++i)
{
File fileSource = new File(unpack_dir + SEPARATOR + sourceDir[i]);
System.err.println(sourceDir[i]);
addDirectory(zout, fileSource, "");
}
//close the ZipOutputStream
zout.close();
System.out.println("Zip file has been created!");
}
catch(IOException ioe)
{
System.out.println("IOException :" + ioe);
}
}
private static void addDirectory(ZipOutputStream zout, File fileSource, String path)
{
//get sub-folder/files list
File[] files = fileSource.listFiles();
path += fileSource.getName() + "/";
System.out.println("Adding directory " + fileSource.getName() + ", Path: " + path);
try {
zout.putNextEntry(new ZipEntry(path + "/"));
} catch (IOException e) {
e.printStackTrace();
}
for(int i=0; i < files.length; i++)
{
//if the file is directory, call the function recursively
if(files[i].isDirectory())
{
System.err.println("Przekazuję dalej: " + files[i] + ", Path: " + path);
addDirectory(zout, files[i], path);
continue;
}
else
{
/*
* we are here means, its file and not directory, so
* add it to the zip file
*/
try
{
System.out.println("Adding file " + path + files[i].getName());
//create byte buffer
byte[] buffer = new byte[1024];
//create object of FileInputStream
FileInputStream fin = new FileInputStream(files[i]);
zout.putNextEntry(new ZipEntry(path + files[i].getName().toLowerCase()));
/*
* After creating entry in the zip file, actually
* write the file.
*/
int length;
while((length = fin.read(buffer)) > 0)
{
zout.write(buffer, 0, length);
}
/*
* After writing the file to ZipOutputStream, use
*
* void closeEntry() method of ZipOutputStream class to
* close the current entry and position the stream to
* write the next entry.
*/
zout.closeEntry();
//close the InputStream
fin.close();
}
catch(IOException ioe)
{
System.out.println("IOException :" + ioe);
}
}
}
}
}