mirror of
https://github.com/tonikelope/megabasterd.git
synced 2025-04-30 06:34:39 +02:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fda0fac577 | ||
![]() |
fed9f142d0 | ||
![]() |
fadb7ea2cc | ||
![]() |
762d3692e9 | ||
![]() |
5378954bb5 | ||
![]() |
d16baf4866 | ||
![]() |
5353110c3e | ||
![]() |
91dafbce45 | ||
![]() |
53c65de717 | ||
![]() |
ba8336e60d |
@ -14,8 +14,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p align="center"><a href="https://youtu.be/5TkBXT7osQI"><b>MegaBasterd DEMO</b></a></p>
|
<p align="center"><a href="https://youtu.be/5TkBXT7osQI"><b>MegaBasterd DEMO</b></a></p>
|
||||||
|
|
||||||
<p align="center"><img src="https://raw.githubusercontent.com/tonikelope/megabasterd/master/src/main/resources/images/ethereum_toni.png"></p>
|
<p align="center"><img src="https://raw.githubusercontent.com/tonikelope/megabasterd/master/coffee.png"><br><img src="https://raw.githubusercontent.com/tonikelope/megabasterd/master/src/main/resources/images/ethereum_toni.png"></p>
|
||||||
|
|
||||||
<p align="center"><a href="https://github.com/tonikelope/megabasterd/issues/385#issuecomment-1019215670">BONUS: Why the f*ck has MegaBasterd stopped downloading?</a></p>
|
<p align="center"><a href="https://github.com/tonikelope/megabasterd/issues/385#issuecomment-1019215670">BONUS: Why the f*ck has MegaBasterd stopped downloading?</a></p>
|
||||||
|
|
||||||
|
<p align="center"><b>IMPORTANT:</b> You are not authorized to use MegaBasterd in any way that violates <a href="https://mega.io/es/terms"><b>MEGA's terms of use</b></a>.</p>
|
||||||
|
BIN
coffee.png
Normal file
BIN
coffee.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
2
pom.xml
2
pom.xml
@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.tonikelope</groupId>
|
<groupId>com.tonikelope</groupId>
|
||||||
<artifactId>MegaBasterd</artifactId>
|
<artifactId>MegaBasterd</artifactId>
|
||||||
<version>8.21</version>
|
<version>8.22</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
|
@ -19,6 +19,7 @@ import java.nio.file.Paths;
|
|||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.crypto.CipherInputStream;
|
import javax.crypto.CipherInputStream;
|
||||||
@ -32,6 +33,8 @@ public class ChunkWriterManager implements Runnable, SecureSingleThreadNotifiabl
|
|||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(ChunkWriterManager.class.getName());
|
private static final Logger LOG = Logger.getLogger(ChunkWriterManager.class.getName());
|
||||||
|
|
||||||
|
private static final ReentrantLock JOIN_CHUNKS_LOCK = new ReentrantLock();
|
||||||
|
|
||||||
public static long calculateChunkOffset(long chunk_id, int size_multi) {
|
public static long calculateChunkOffset(long chunk_id, int size_multi) {
|
||||||
long[] offs = {0, 128, 384, 768, 1280, 1920, 2688};
|
long[] offs = {0, 128, 384, 768, 1280, 1920, 2688};
|
||||||
|
|
||||||
@ -179,71 +182,89 @@ public class ChunkWriterManager implements Runnable, SecureSingleThreadNotifiabl
|
|||||||
LOG.log(Level.INFO, "{0} ChunkWriterManager LAST CHUNK WRITTEN -> [{1}] {2} {3}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written, _bytes_written, _download.getFile_name()});
|
LOG.log(Level.INFO, "{0} ChunkWriterManager LAST CHUNK WRITTEN -> [{1}] {2} {3}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written, _bytes_written, _download.getFile_name()});
|
||||||
boolean download_finished = false;
|
boolean download_finished = false;
|
||||||
if (_file_size > 0) {
|
if (_file_size > 0) {
|
||||||
while (!_exit && (!_download.isStopped() || !_download.getChunkworkers().isEmpty()) && _bytes_written < _file_size) {
|
|
||||||
|
|
||||||
if (!download_finished && _download.getProgress() == _file_size) {
|
try {
|
||||||
|
|
||||||
finishDownload();
|
while (!_exit && (!_download.isStopped() || !_download.getChunkworkers().isEmpty()) && _bytes_written < _file_size) {
|
||||||
download_finished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean chunk_io_error;
|
if (!JOIN_CHUNKS_LOCK.isHeldByCurrentThread()) {
|
||||||
|
LOG.log(Level.INFO, "{0} ChunkWriterManager: JOIN LOCK LOCKED FOR {1}", new Object[]{Thread.currentThread().getName(), _download.getFile_name()});
|
||||||
do {
|
JOIN_CHUNKS_LOCK.lock();
|
||||||
|
|
||||||
chunk_io_error = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
File chunk_file = new File(getChunks_dir() + "/" + MiscTools.HashString("sha1", _download.getUrl()) + ".chunk" + String.valueOf(_last_chunk_id_written + 1));
|
|
||||||
|
|
||||||
while (chunk_file.exists() && chunk_file.canRead() && chunk_file.canWrite() && chunk_file.length() > 0) {
|
|
||||||
|
|
||||||
if (!download_finished && _download.getProgress() == _file_size) {
|
|
||||||
|
|
||||||
finishDownload();
|
|
||||||
download_finished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE];
|
|
||||||
|
|
||||||
int reads;
|
|
||||||
|
|
||||||
try (CipherInputStream cis = new CipherInputStream(new BufferedInputStream(new FileInputStream(chunk_file)), genDecrypter("AES", "AES/CTR/NoPadding", _byte_file_key, forwardMEGALinkKeyIV(_byte_iv, _bytes_written)))) {
|
|
||||||
while ((reads = cis.read(buffer)) != -1) {
|
|
||||||
_download.getOutput_stream().write(buffer, 0, reads);
|
|
||||||
}
|
|
||||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException ex) {
|
|
||||||
LOG.log(Level.SEVERE, ex.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
_bytes_written += chunk_file.length();
|
|
||||||
|
|
||||||
_last_chunk_id_written++;
|
|
||||||
|
|
||||||
LOG.log(Level.INFO, "{0} ChunkWriterManager has written to disk chunk [{1}] {2} {3} {4}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written, _bytes_written, _download.calculateLastWrittenChunk(_bytes_written), _download.getFile_name()});
|
|
||||||
|
|
||||||
chunk_file.delete();
|
|
||||||
|
|
||||||
chunk_file = new File(getChunks_dir() + "/" + MiscTools.HashString("sha1", _download.getUrl()) + ".chunk" + String.valueOf(_last_chunk_id_written + 1));
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
chunk_io_error = true;
|
|
||||||
LOG.log(Level.WARNING, ex.getMessage());
|
|
||||||
MiscTools.pausar(1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (chunk_io_error);
|
if (!download_finished && _download.getProgress() == _file_size) {
|
||||||
|
|
||||||
if (!_exit && (!_download.isStopped() || !_download.getChunkworkers().isEmpty()) && _bytes_written < _file_size) {
|
finishDownload();
|
||||||
|
download_finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
LOG.log(Level.INFO, "{0} ChunkWriterManager waiting for chunk [{1}] {2}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written + 1, _download.getFile_name()});
|
boolean chunk_io_error;
|
||||||
|
|
||||||
secureWait();
|
do {
|
||||||
|
|
||||||
|
chunk_io_error = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
File chunk_file = new File(getChunks_dir() + "/" + MiscTools.HashString("sha1", _download.getUrl()) + ".chunk" + String.valueOf(_last_chunk_id_written + 1));
|
||||||
|
|
||||||
|
while (chunk_file.exists() && chunk_file.canRead() && chunk_file.canWrite() && chunk_file.length() > 0) {
|
||||||
|
|
||||||
|
if (!download_finished && _download.getProgress() == _file_size) {
|
||||||
|
|
||||||
|
finishDownload();
|
||||||
|
download_finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] buffer = new byte[MainPanel.DEFAULT_BYTE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
int reads;
|
||||||
|
|
||||||
|
try (CipherInputStream cis = new CipherInputStream(new BufferedInputStream(new FileInputStream(chunk_file)), genDecrypter("AES", "AES/CTR/NoPadding", _byte_file_key, forwardMEGALinkKeyIV(_byte_iv, _bytes_written)))) {
|
||||||
|
while ((reads = cis.read(buffer)) != -1) {
|
||||||
|
_download.getOutput_stream().write(buffer, 0, reads);
|
||||||
|
}
|
||||||
|
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException ex) {
|
||||||
|
LOG.log(Level.SEVERE, ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
_bytes_written += chunk_file.length();
|
||||||
|
|
||||||
|
_last_chunk_id_written++;
|
||||||
|
|
||||||
|
LOG.log(Level.INFO, "{0} ChunkWriterManager has written to disk chunk [{1}] {2} {3} {4}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written, _bytes_written, _download.calculateLastWrittenChunk(_bytes_written), _download.getFile_name()});
|
||||||
|
|
||||||
|
chunk_file.delete();
|
||||||
|
|
||||||
|
chunk_file = new File(getChunks_dir() + "/" + MiscTools.HashString("sha1", _download.getUrl()) + ".chunk" + String.valueOf(_last_chunk_id_written + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
chunk_io_error = true;
|
||||||
|
LOG.log(Level.WARNING, ex.getMessage());
|
||||||
|
MiscTools.pausar(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (chunk_io_error);
|
||||||
|
|
||||||
|
if (!_exit && (!_download.isStopped() || !_download.getChunkworkers().isEmpty()) && _bytes_written < _file_size) {
|
||||||
|
|
||||||
|
LOG.log(Level.INFO, "{0} ChunkWriterManager waiting for chunk [{1}] {2}...", new Object[]{Thread.currentThread().getName(), _last_chunk_id_written + 1, _download.getFile_name()});
|
||||||
|
|
||||||
|
if (JOIN_CHUNKS_LOCK.isHeldByCurrentThread() && JOIN_CHUNKS_LOCK.isLocked()) {
|
||||||
|
LOG.log(Level.INFO, "{0} ChunkWriterManager: JOIN LOCK RELEASED FOR {1}", new Object[]{Thread.currentThread().getName(), _download.getFile_name()});
|
||||||
|
JOIN_CHUNKS_LOCK.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
secureWait();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (JOIN_CHUNKS_LOCK.isHeldByCurrentThread() && JOIN_CHUNKS_LOCK.isLocked()) {
|
||||||
|
LOG.log(Level.INFO, "{0} ChunkWriterManager: JOIN LOCK RELEASED FOR {1}", new Object[]{Thread.currentThread().getName(), _download.getFile_name()});
|
||||||
|
JOIN_CHUNKS_LOCK.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_bytes_written == _file_size && MiscTools.isDirEmpty(Paths.get(getChunks_dir()))) {
|
if (_bytes_written == _file_size && MiscTools.isDirEmpty(Paths.get(getChunks_dir()))) {
|
||||||
|
@ -41,7 +41,6 @@ public class FileSplitterDialog extends javax.swing.JDialog {
|
|||||||
private final MainPanel _main_panel;
|
private final MainPanel _main_panel;
|
||||||
private File[] _files = null;
|
private File[] _files = null;
|
||||||
private File _output_dir = null;
|
private File _output_dir = null;
|
||||||
private volatile String _sha1 = null;
|
|
||||||
private volatile long _progress = 0L;
|
private volatile long _progress = 0L;
|
||||||
private volatile Path _current_part = null;
|
private volatile Path _current_part = null;
|
||||||
private volatile int _current_file = 0;
|
private volatile int _current_file = 0;
|
||||||
@ -86,17 +85,6 @@ public class FileSplitterDialog extends javax.swing.JDialog {
|
|||||||
|
|
||||||
private boolean _splitFile(int i) throws IOException {
|
private boolean _splitFile(int i) throws IOException {
|
||||||
|
|
||||||
_sha1 = "";
|
|
||||||
|
|
||||||
THREAD_POOL.execute(() -> {
|
|
||||||
|
|
||||||
try {
|
|
||||||
_sha1 = MiscTools.computeFileSHA1(new File(_files[i].getAbsolutePath()));
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(FileSplitterDialog.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this._progress = 0L;
|
this._progress = 0L;
|
||||||
|
|
||||||
int mBperSplit = Integer.parseInt(this.split_size_text.getText());
|
int mBperSplit = Integer.parseInt(this.split_size_text.getText());
|
||||||
@ -135,20 +123,6 @@ public class FileSplitterDialog extends javax.swing.JDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ("".equals(_sha1)) {
|
|
||||||
MiscTools.GUIRunAndWait(() -> {
|
|
||||||
|
|
||||||
split_button.setText(LabelTranslatorSingleton.getInstance().translate("GENERATING SHA1, please wait..."));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
MiscTools.pausar(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_sha1 != null) {
|
|
||||||
Files.writeString(Paths.get(this._files[i].getAbsolutePath() + ".sha1"), _sha1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,9 +169,13 @@ public class FileSplitterDialog extends javax.swing.JDialog {
|
|||||||
monitorProgress(f, byteSize);
|
monitorProgress(f, byteSize);
|
||||||
|
|
||||||
if (!_exit) {
|
if (!_exit) {
|
||||||
|
long dest_bytes_copied = Files.exists(fileName) ? Files.size(fileName) : 0;
|
||||||
|
|
||||||
try (RandomAccessFile toFile = new RandomAccessFile(fileName.toFile(), "rw"); FileChannel toChannel = toFile.getChannel()) {
|
try (RandomAccessFile toFile = new RandomAccessFile(fileName.toFile(), "rw"); FileChannel toChannel = toFile.getChannel()) {
|
||||||
sourceChannel.position(position);
|
while (dest_bytes_copied < byteSize) {
|
||||||
toChannel.transferFrom(sourceChannel, 0, byteSize);
|
sourceChannel.position(position + dest_bytes_copied);
|
||||||
|
dest_bytes_copied += toChannel.transferFrom(sourceChannel, dest_bytes_copied, byteSize - dest_bytes_copied);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ import javax.swing.UIManager;
|
|||||||
*/
|
*/
|
||||||
public final class MainPanel {
|
public final class MainPanel {
|
||||||
|
|
||||||
public static final String VERSION = "8.21";
|
public static final String VERSION = "8.22";
|
||||||
public static final boolean FORCE_SMART_PROXY = false; //TRUE FOR DEBUGING SMART PROXY
|
public static final boolean FORCE_SMART_PROXY = false; //TRUE FOR DEBUGING SMART PROXY
|
||||||
public static final int THROTTLE_SLICE_SIZE = 16 * 1024;
|
public static final int THROTTLE_SLICE_SIZE = 16 * 1024;
|
||||||
public static final int DEFAULT_BYTE_BUFFER_SIZE = 16 * 1024;
|
public static final int DEFAULT_BYTE_BUFFER_SIZE = 16 * 1024;
|
||||||
|
@ -276,6 +276,8 @@ public final class MainPanelView extends javax.swing.JFrame {
|
|||||||
|
|
||||||
if (dialog.getUpload_log_checkbox().isSelected()) {
|
if (dialog.getUpload_log_checkbox().isSelected()) {
|
||||||
|
|
||||||
|
MiscTools.createUploadLogDir();
|
||||||
|
|
||||||
File upload_log = new File(MiscTools.UPLOAD_LOGS_DIR + "/megabasterd_upload_" + parent_node + ".log");
|
File upload_log = new File(MiscTools.UPLOAD_LOGS_DIR + "/megabasterd_upload_" + parent_node + ".log");
|
||||||
upload_log.createNewFile();
|
upload_log.createNewFile();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user